freesolo-flash-dev 1.2.89__tar.gz → 1.2.94__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 (612) hide show
  1. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/PKG-INFO +1 -1
  2. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/__init__.py +11 -24
  3. freesolo_flash_dev-1.2.94/flash/cli/commands/worker_output.py +67 -0
  4. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/ui/heartbeat.py +27 -0
  5. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/ui/render.py +1 -0
  6. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/plan/kv_sizing.py +20 -8
  7. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/opd_train.py +1 -1
  8. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/opd_train_runner.py +5 -1
  9. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/verl_config.py +17 -8
  10. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/poll.py +3 -0
  11. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/platform/runtime.py +4 -3
  12. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/pyproject.toml +2 -2
  13. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_commands.py +54 -0
  14. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_render_theme.py +24 -0
  15. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_jobs.py +1 -1
  16. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_opd_train.py +32 -0
  17. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_resume_on_retry.py +4 -0
  18. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_rl_train.py +67 -16
  19. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_server_api.py +49 -0
  20. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/uv.lock +1 -1
  21. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.dockerignore +0 -0
  22. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.env.example +0 -0
  23. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/CODEOWNERS +0 -0
  24. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  25. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  26. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  27. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  28. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/dependabot.yml +0 -0
  29. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/auto-rebake.yml +0 -0
  30. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/bake-kernel-cache.yml +0 -0
  31. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/ci.yml +0 -0
  32. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/dev-kernel-cache.yml +0 -0
  33. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/main-source-guard.yml +0 -0
  34. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/notify-tests-repo.yml +0 -0
  35. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/production-kernel-cache-ready.yml +0 -0
  36. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/publish-dev.yml +0 -0
  37. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/publish-image.yml +0 -0
  38. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/publish.yml +0 -0
  39. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/version-parity.yml +0 -0
  40. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/worker-image.yml +0 -0
  41. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.gitignore +0 -0
  42. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/CHANGELOG.md +0 -0
  43. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/CODE_OF_CONDUCT.md +0 -0
  44. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/CONTRIBUTING.md +0 -0
  45. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/Dockerfile +0 -0
  46. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/Dockerfile.worker +0 -0
  47. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/LICENSE +0 -0
  48. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/NOTICE +0 -0
  49. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/README.md +0 -0
  50. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/SECURITY.md +0 -0
  51. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/SELF_HOSTING.md +0 -0
  52. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/build/kernel_cache/.gitignore +0 -0
  53. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/build/kernel_cache/.keep +0 -0
  54. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/deploy/infisical/README.md +0 -0
  55. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/deploy/infisical/entrypoint.sh +0 -0
  56. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/docker/Dockerfile.kernelcache +0 -0
  57. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/docker/Dockerfile.kernelcache.relayer +0 -0
  58. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/docker/bake_kernel_cache.py +0 -0
  59. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/docker/bake_pod_entry.py +0 -0
  60. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/docker/extract_cudart_fix.py +0 -0
  61. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/docker/kernel_fingerprint.py +0 -0
  62. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/docker/make_rp_handler.py +0 -0
  63. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/__init__.py +0 -0
  64. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/_internal/__init__.py +0 -0
  65. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/_internal/channel.py +0 -0
  66. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/_internal/diagnostics.py +0 -0
  67. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/_internal/fileio.py +0 -0
  68. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/_internal/logging.py +0 -0
  69. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/_internal/paths.py +0 -0
  70. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/adapters/__init__.py +0 -0
  71. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/adapters/artifacts.py +0 -0
  72. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/adapters/fused_experts.py +0 -0
  73. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/adapters/lora_rank.py +0 -0
  74. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/adapters/targets.py +0 -0
  75. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/__init__.py +0 -0
  76. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/__main__.py +0 -0
  77. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/deploy.py +0 -0
  78. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/__init__.py +0 -0
  79. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/episode.py +0 -0
  80. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/eval.py +0 -0
  81. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/eval_args.py +0 -0
  82. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/imports.py +0 -0
  83. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/list.py +0 -0
  84. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/push.py +0 -0
  85. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/retained.py +0 -0
  86. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/setup.py +0 -0
  87. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/setup_wandb.py +0 -0
  88. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/test.py +0 -0
  89. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/test_evaluations.py +0 -0
  90. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/test_params.py +0 -0
  91. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/test_warnings.py +0 -0
  92. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/prompt_budget.py +0 -0
  93. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/traces.py +0 -0
  94. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/train_cost.py +0 -0
  95. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/scaffold/TRAINING.md +0 -0
  96. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/scaffold/__init__.py +0 -0
  97. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/ui/__init__.py +0 -0
  98. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/ui/cost.py +0 -0
  99. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/ui/env_panels.py +0 -0
  100. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/ui/tables.py +0 -0
  101. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/ui/tty.py +0 -0
  102. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/client/__init__.py +0 -0
  103. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/client/config.py +0 -0
  104. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/client/freesolo_api.py +0 -0
  105. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/client/http.py +0 -0
  106. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/client/runtime_secrets.py +0 -0
  107. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/client/shapes.py +0 -0
  108. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/client/specs.py +0 -0
  109. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/client/streaming.py +0 -0
  110. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/content/__init__.py +0 -0
  111. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/content/image_descriptors.py +0 -0
  112. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/content/multimodal.py +0 -0
  113. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/content/structured_outputs.py +0 -0
  114. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/content/thinking.py +0 -0
  115. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/core/__init__.py +0 -0
  116. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/core/catalog.py +0 -0
  117. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/core/grpo.py +0 -0
  118. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/core/spec.py +0 -0
  119. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/core/spec_persistence.py +0 -0
  120. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cost/__init__.py +0 -0
  121. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cost/analytical.py +0 -0
  122. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cost/facts.py +0 -0
  123. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cost/spec.py +0 -0
  124. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cost/types.py +0 -0
  125. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/__init__.py +0 -0
  126. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/huggingface.py +0 -0
  127. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/plan/__init__.py +0 -0
  128. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/plan/model_config_probe.py +0 -0
  129. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/plan/prompt_budget.py +0 -0
  130. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/plan/recipe.py +0 -0
  131. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/plan/steps.py +0 -0
  132. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/plan/vram.py +0 -0
  133. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/profiling/__init__.py +0 -0
  134. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/profiling/dataset_profile.py +0 -0
  135. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/profiling/image_tokens.py +0 -0
  136. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/profiling/reasoning_render.py +0 -0
  137. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/profiling/sft_image_rows.py +0 -0
  138. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/profiling/sft_workload.py +0 -0
  139. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/profiling/tokenizer.py +0 -0
  140. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/profiling/workload_profile.py +0 -0
  141. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/result/__init__.py +0 -0
  142. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/result/accounting.py +0 -0
  143. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/result/rollout_samples.py +0 -0
  144. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/__init__.py +0 -0
  145. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/__main__.py +0 -0
  146. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/backend_common.py +0 -0
  147. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/entry/__init__.py +0 -0
  148. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/entry/opd.py +0 -0
  149. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/entry/rl.py +0 -0
  150. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/entry/sft.py +0 -0
  151. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/io/__init__.py +0 -0
  152. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/io/heartbeat.py +0 -0
  153. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/io/hf.py +0 -0
  154. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/io/prefetch.py +0 -0
  155. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/io/wandb_log.py +0 -0
  156. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/model/__init__.py +0 -0
  157. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/model/adapter.py +0 -0
  158. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/model/chatml_mask.py +0 -0
  159. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/model/decoding.py +0 -0
  160. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/model/lora.py +0 -0
  161. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/model/packing.py +0 -0
  162. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/perf/__init__.py +0 -0
  163. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/perf/diagnostics.py +0 -0
  164. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/perf/lifecycle.py +0 -0
  165. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/perf/liger.py +0 -0
  166. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/perf/memory.py +0 -0
  167. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/rl_train.py +0 -0
  168. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/rl_train_runner.py +0 -0
  169. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/runtime/__init__.py +0 -0
  170. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
  171. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
  172. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/runtime/rng.py +0 -0
  173. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/score_batcher.py +0 -0
  174. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/sft_train.py +0 -0
  175. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/sft_train_runner.py +0 -0
  176. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/teacher/__init__.py +0 -0
  177. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/teacher/client.py +0 -0
  178. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/teacher/encoding.py +0 -0
  179. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
  180. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/__init__.py +0 -0
  181. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/core/__init__.py +0 -0
  182. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/core/checkpoint_lifecycle.py +0 -0
  183. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/core/child/__init__.py +0 -0
  184. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/core/child/glue.py +0 -0
  185. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/core/child/runtime.py +0 -0
  186. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/core/step_timing.py +0 -0
  187. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/finalize.py +0 -0
  188. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/__init__.py +0 -0
  189. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/batching.py +0 -0
  190. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/bridge.py +0 -0
  191. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/bridge_failures.py +0 -0
  192. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/child/__init__.py +0 -0
  193. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/child/bridge.py +0 -0
  194. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/child/entry.py +0 -0
  195. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/child/multiturn.py +0 -0
  196. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/child/plugin.py +0 -0
  197. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/child/replay_guard.py +0 -0
  198. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/child/runtime.py +0 -0
  199. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/child/structured.py +0 -0
  200. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/failures.py +0 -0
  201. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/gkd.py +0 -0
  202. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/multiturn_media.py +0 -0
  203. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
  204. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/overrides.py +0 -0
  205. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/prompts.py +0 -0
  206. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/reporting.py +0 -0
  207. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/scoring.py +0 -0
  208. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/state.py +0 -0
  209. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/validation.py +0 -0
  210. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/__init__.py +0 -0
  211. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/checkpoints.py +0 -0
  212. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/child/__init__.py +0 -0
  213. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/child/entry.py +0 -0
  214. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/child/multiturn.py +0 -0
  215. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/child/patches.py +0 -0
  216. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/child/plugin.py +0 -0
  217. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/config.py +0 -0
  218. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/identity.py +0 -0
  219. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/inputs.py +0 -0
  220. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/multi_turn.py +0 -0
  221. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/reward_module.py +0 -0
  222. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/scoring.py +0 -0
  223. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/single_turn.py +0 -0
  224. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/sft/__init__.py +0 -0
  225. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/sft/checkpoints.py +0 -0
  226. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/sft/child/entry.py +0 -0
  227. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/sft/child/plugin.py +0 -0
  228. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/sft/config.py +0 -0
  229. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/verl/__init__.py +0 -0
  230. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/verl/capabilities.py +0 -0
  231. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/verl/checkpoints.py +0 -0
  232. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/verl/child_io.py +0 -0
  233. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/verl/diagnostics.py +0 -0
  234. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/verl/parallelism.py +0 -0
  235. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/verl/parent_work.py +0 -0
  236. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/verl/process_census.py +0 -0
  237. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker_entrypoint.py +0 -0
  238. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/__init__.py +0 -0
  239. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/adapter.py +0 -0
  240. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/base.py +0 -0
  241. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/cache_security.py +0 -0
  242. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/dataset_selection.py +0 -0
  243. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/evaluations.py +0 -0
  244. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/identity.py +0 -0
  245. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/loader.py +0 -0
  246. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/namespace_listing.py +0 -0
  247. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/package/__init__.py +0 -0
  248. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/package/direct_tokens.py +0 -0
  249. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/package/limits.py +0 -0
  250. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/package/unpack.py +0 -0
  251. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/pull.py +0 -0
  252. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/staged.py +0 -0
  253. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/__init__.py +0 -0
  254. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/__init__.py +0 -0
  255. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/auth.py +0 -0
  256. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/bootstrap.py +0 -0
  257. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/bootstrap_console.py +0 -0
  258. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
  259. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
  260. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/deadline.py +0 -0
  261. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/host/__init__.py +0 -0
  262. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/host/deadline_sleep.py +0 -0
  263. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/host/failmark.py +0 -0
  264. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/host/hostlog.py +0 -0
  265. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/http.py +0 -0
  266. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/instance.py +0 -0
  267. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/poll_instance.py +0 -0
  268. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/provider.py +0 -0
  269. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/terminal_artifacts.py +0 -0
  270. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/worker.py +0 -0
  271. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/allocator.py +0 -0
  272. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/artifacts/__init__.py +0 -0
  273. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/artifacts/hf.py +0 -0
  274. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/artifacts/preload_runpod.py +0 -0
  275. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/artifacts/weight_cache.py +0 -0
  276. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/base.py +0 -0
  277. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/fit_errors.py +0 -0
  278. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/lambda_/__init__.py +0 -0
  279. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/lambda_/api.py +0 -0
  280. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/lambda_/auth.py +0 -0
  281. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/lambda_/gpus.py +0 -0
  282. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/lambda_/jobs/__init__.py +0 -0
  283. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/lambda_/jobs/builders.py +0 -0
  284. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/lambda_/jobs/reap.py +0 -0
  285. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/lambda_/preflight.py +0 -0
  286. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/lambda_/pricing.py +0 -0
  287. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/preflight.py +0 -0
  288. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/realized.py +0 -0
  289. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/__init__.py +0 -0
  290. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/api.py +0 -0
  291. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/auth.py +0 -0
  292. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/cost.py +0 -0
  293. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/gpus.py +0 -0
  294. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/job_execution.py +0 -0
  295. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/jobs.py +0 -0
  296. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/preflight.py +0 -0
  297. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/pricing.py +0 -0
  298. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/resources.py +0 -0
  299. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/serverless/__init__.py +0 -0
  300. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/serverless/endpoints.py +0 -0
  301. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/sharding.py +0 -0
  302. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/vast/__init__.py +0 -0
  303. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/vast/api.py +0 -0
  304. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/vast/auth.py +0 -0
  305. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/vast/jobs/__init__.py +0 -0
  306. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/vast/jobs/builders.py +0 -0
  307. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/vast/preflight.py +0 -0
  308. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/vast/pricing.py +0 -0
  309. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/py.typed +0 -0
  310. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/__init__.py +0 -0
  311. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/artifacts.py +0 -0
  312. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/attempts.py +0 -0
  313. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/costs.py +0 -0
  314. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/deadlines.py +0 -0
  315. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/preparation.py +0 -0
  316. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/reconciliation.py +0 -0
  317. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/results/__init__.py +0 -0
  318. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/results/checkpoints.py +0 -0
  319. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/results/verified_revisions.py +0 -0
  320. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/status.py +0 -0
  321. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/submit.py +0 -0
  322. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/supervise/__init__.py +0 -0
  323. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/supervise/attach.py +0 -0
  324. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/supervise/deploy.py +0 -0
  325. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/supervise/lifecycle.py +0 -0
  326. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/supervise/recovery.py +0 -0
  327. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/supervise/retry_decision.py +0 -0
  328. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/supervise/seed_submission.py +0 -0
  329. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/supervise/transitions.py +0 -0
  330. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/weight_cache.py +0 -0
  331. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runtime_capsule/__init__.py +0 -0
  332. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runtime_capsule/build.py +0 -0
  333. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runtime_capsule/manifest.py +0 -0
  334. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runtime_capsule/profiles.py +0 -0
  335. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/schema/__init__.py +0 -0
  336. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/schema/fields.py +0 -0
  337. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/__init__.py +0 -0
  338. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/adapter_check.py +0 -0
  339. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/deploy.py +0 -0
  340. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/errors.py +0 -0
  341. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/export.py +0 -0
  342. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/preflight.py +0 -0
  343. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/responses.py +0 -0
  344. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/streaming.py +0 -0
  345. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/thinking.py +0 -0
  346. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/urls.py +0 -0
  347. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/__init__.py +0 -0
  348. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/__main__.py +0 -0
  349. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/app.py +0 -0
  350. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/billing/__init__.py +0 -0
  351. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/billing/charges.py +0 -0
  352. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/billing/retry.py +0 -0
  353. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/__init__.py +0 -0
  354. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/checkpoints.py +0 -0
  355. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/environment_registry.py +0 -0
  356. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/envs.py +0 -0
  357. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/projects.py +0 -0
  358. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/reconcile.py +0 -0
  359. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/repo_cleanup.py +0 -0
  360. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/run_registry.py +0 -0
  361. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/teacher_broker.py +0 -0
  362. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/teacher_errors.py +0 -0
  363. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/teacher_requests.py +0 -0
  364. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/platform/__init__.py +0 -0
  365. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/platform/auth.py +0 -0
  366. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/platform/db.py +0 -0
  367. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/platform/deps.py +0 -0
  368. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/platform/internal_client.py +0 -0
  369. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/platform/locks.py +0 -0
  370. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/routes/__init__.py +0 -0
  371. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/routes/envs.py +0 -0
  372. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/routes/meta.py +0 -0
  373. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/routes/runs.py +0 -0
  374. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/routes/serving.py +0 -0
  375. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/routes/serving_completion.py +0 -0
  376. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/routes/serving_revisions.py +0 -0
  377. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/routes/serving_smoke.py +0 -0
  378. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/routes/teacher.py +0 -0
  379. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/source_snapshot.py +0 -0
  380. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/teacher/__init__.py +0 -0
  381. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/teacher/limits.py +0 -0
  382. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/teacher/provider_status.py +0 -0
  383. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/teacher/retry_contract.py +0 -0
  384. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/scripts/build_dev_dist.py +0 -0
  385. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/scripts/check_file_size.py +0 -0
  386. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/scripts/check_function_size.py +0 -0
  387. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/scripts/check_rollout_identity_actor.py +0 -0
  388. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/scripts/check_verl_pin_exists.py +0 -0
  389. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/scripts/scrub_history.sh +0 -0
  390. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/__init__.py +0 -0
  391. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/_helpers/__init__.py +0 -0
  392. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/_helpers/profile.py +0 -0
  393. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/_helpers/runner.py +0 -0
  394. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/_helpers/source_snapshot.py +0 -0
  395. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/_helpers/specs.py +0 -0
  396. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/_helpers/teacher.py +0 -0
  397. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/_helpers/vast.py +0 -0
  398. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/capture_image_sft_processor_oracle.py +0 -0
  399. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/conftest.py +0 -0
  400. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/fixtures/image_sft_processor_oracle.json +0 -0
  401. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/fixtures/qwen35_08b_target_metadata.json +0 -0
  402. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/live/__init__.py +0 -0
  403. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/live/conftest.py +0 -0
  404. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/live/test_lambda_live.py +0 -0
  405. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/live/test_runpod_live.py +0 -0
  406. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/live/test_sft_thinking_render_live.py +0 -0
  407. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/live/test_vast_live.py +0 -0
  408. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_accounting_coverage.py +0 -0
  409. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_adapter_shard_completeness.py +0 -0
  410. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_agent_flash_cli_contract.py +0 -0
  411. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_algorithms.py +0 -0
  412. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_allocator.py +0 -0
  413. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_backend_common.py +0 -0
  414. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_backend_jobspec_contract.py +0 -0
  415. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_bake_kernel_cache.py +0 -0
  416. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_base_model_provenance.py +0 -0
  417. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_billing_retry.py +0 -0
  418. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_build_context_contract.py +0 -0
  419. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cancel_remote.py +0 -0
  420. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_catalog_consistency.py +0 -0
  421. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_catalog_only_models.py +0 -0
  422. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_charge_pricing.py +0 -0
  423. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_checkpoint_lifecycle.py +0 -0
  424. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_checkpoints.py +0 -0
  425. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_commands_coverage.py +0 -0
  426. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_credential_shadowing.py +0 -0
  427. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_errors.py +0 -0
  428. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_estimate.py +0 -0
  429. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_gpus_flag.py +0 -0
  430. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_help.py +0 -0
  431. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_main_coverage.py +0 -0
  432. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_managed.py +0 -0
  433. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_render_coverage.py +0 -0
  434. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_traces.py +0 -0
  435. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_wandb_warning.py +0 -0
  436. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_client.py +0 -0
  437. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_client_import_purity.py +0 -0
  438. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_client_server_integration.py +0 -0
  439. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_client_stream_reads.py +0 -0
  440. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_config_env_vars.py +0 -0
  441. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_config_overrides.py +0 -0
  442. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_console_upload.py +0 -0
  443. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_controlled_experiment_repairs.py +0 -0
  444. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cost_analytical.py +0 -0
  445. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cost_equation.py +0 -0
  446. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cost_estimate.py +0 -0
  447. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cost_hardware.py +0 -0
  448. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cost_models.py +0 -0
  449. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_dataset_profile.py +0 -0
  450. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_deploy_alias_move_warning.py +0 -0
  451. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_deploy_latency.py +0 -0
  452. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_dev_channel.py +0 -0
  453. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_disk_gb.py +0 -0
  454. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_endpoint_name.py +0 -0
  455. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_cache_evict.py +0 -0
  456. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_delete.py +0 -0
  457. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_download.py +0 -0
  458. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_download_api.py +0 -0
  459. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_evaluations.py +0 -0
  460. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_list_api.py +0 -0
  461. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_list_cli.py +0 -0
  462. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_list_hub.py +0 -0
  463. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_no_install.py +0 -0
  464. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_publish.py +0 -0
  465. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_pull.py +0 -0
  466. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_pull_coverage.py +0 -0
  467. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_pull_loader_coverage.py +0 -0
  468. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_pull_managed_control_plane.py +0 -0
  469. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_push.py +0 -0
  470. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_rate_limit_resolve.py +0 -0
  471. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_ref_pinning.py +0 -0
  472. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_test.py +0 -0
  473. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_envs_coverage.py +0 -0
  474. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_export.py +0 -0
  475. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_flash_mvp.py +0 -0
  476. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_flash_worker.py +0 -0
  477. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_flashinfer_cache_dirs.py +0 -0
  478. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_freesolo_api_transport.py +0 -0
  479. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_fused_expert_warmstart.py +0 -0
  480. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_github_urlopen_retry.py +0 -0
  481. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_gpu_type_single_field.py +0 -0
  482. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_gpus.py +0 -0
  483. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_grpo_params.py +0 -0
  484. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_grpo_process_census.py +0 -0
  485. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_grpo_resident_sizing.py +0 -0
  486. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_grpo_reward_batching.py +0 -0
  487. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_grpo_rollout_contract.py +0 -0
  488. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_grpo_rollout_identity.py +0 -0
  489. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_health_liveness.py +0 -0
  490. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_hf_retry.py +0 -0
  491. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_idle_endpoint_reaper.py +0 -0
  492. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_image_environment_capability.py +0 -0
  493. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_image_incremental_processor.py +0 -0
  494. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_image_sft_markers.py +0 -0
  495. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_image_sft_processor_parity.py +0 -0
  496. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_image_tokens.py +0 -0
  497. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_infisical_secrets.py +0 -0
  498. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_instance_bootstrap_coverage.py +0 -0
  499. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_internal_client.py +0 -0
  500. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_kernel_cache.py +0 -0
  501. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_kernel_fingerprint.py +0 -0
  502. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_kv_util.py +0 -0
  503. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_lambda_api_coverage.py +0 -0
  504. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_lambda_runner.py +0 -0
  505. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_logging.py +0 -0
  506. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_login_perms.py +0 -0
  507. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_lora_rank_coverage.py +0 -0
  508. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_lora_rank_nested_rung.py +0 -0
  509. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_lora_rank_preflight.py +0 -0
  510. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_lora_targeting.py +0 -0
  511. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_lora_targeting_pinned_verl.py +0 -0
  512. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_managed_config_fields.py +0 -0
  513. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_managed_hf_repo.py +0 -0
  514. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_metrics_schema_agent_contract.py +0 -0
  515. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_mig_guard.py +0 -0
  516. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_multi_gpu_gate.py +0 -0
  517. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_multimodal_training.py +0 -0
  518. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_named_reward_metrics.py +0 -0
  519. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_oom_escalate_gpu.py +0 -0
  520. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_opd.py +0 -0
  521. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_opd_limits.py +0 -0
  522. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_opd_multiturn_eos_boundary.py +0 -0
  523. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_opd_multiturn_failure_exit.py +0 -0
  524. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_opd_replay_guard.py +0 -0
  525. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_opd_resume_safety.py +0 -0
  526. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_orchestrator_flash.py +0 -0
  527. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_packing.py +0 -0
  528. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_packing_coverage.py +0 -0
  529. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_parasail_teacher.py +0 -0
  530. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_persisted_spec_envelope.py +0 -0
  531. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_poll_helpers.py +0 -0
  532. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_preflight.py +0 -0
  533. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_projects.py +0 -0
  534. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_prompt_budget.py +0 -0
  535. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_provider_preflight_coverage.py +0 -0
  536. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_provider_routing.py +0 -0
  537. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_provider_teardown_robustness.py +0 -0
  538. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_providers_symmetry.py +0 -0
  539. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_realized_cost.py +0 -0
  540. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_repo_cleanup.py +0 -0
  541. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_resolve_params_b.py +0 -0
  542. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_rollout_samples.py +0 -0
  543. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_runmgmt.py +0 -0
  544. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_runpod_api_delete.py +0 -0
  545. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_runpod_key_fingerprint.py +0 -0
  546. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_runpod_key_waterfall.py +0 -0
  547. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_runtime_capsule.py +0 -0
  548. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_serve.py +0 -0
  549. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_serve_reasoning_content.py +0 -0
  550. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_server_app_coverage.py +0 -0
  551. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_server_auth_singleflight.py +0 -0
  552. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_server_billing.py +0 -0
  553. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_server_checkpoints_coverage.py +0 -0
  554. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_server_db.py +0 -0
  555. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_server_envs_coverage.py +0 -0
  556. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_server_locks_coverage.py +0 -0
  557. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_server_standalone.py +0 -0
  558. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_serving_context_preflight.py +0 -0
  559. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_serving_contract.py +0 -0
  560. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_serving_schema_coverage.py +0 -0
  561. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_sft_chunked_nll.py +0 -0
  562. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_sft_example_selection.py +0 -0
  563. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_sft_gc_off.py +0 -0
  564. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_sft_max_context.py +0 -0
  565. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_sft_startup_block.py +0 -0
  566. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_sft_train.py +0 -0
  567. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_sft_workload.py +0 -0
  568. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_source_attestation_flow.py +0 -0
  569. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_source_snapshot.py +0 -0
  570. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_spec_and_validation.py +0 -0
  571. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_spec_contract_bytes.py +0 -0
  572. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_staged_environment.py +0 -0
  573. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_step_floor.py +0 -0
  574. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_step_metrics.py +0 -0
  575. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_step_timing.py +0 -0
  576. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_structured_outputs.py +0 -0
  577. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_teacher_broker.py +0 -0
  578. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_teacher_encoding_contract.py +0 -0
  579. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_terminal_artifacts.py +0 -0
  580. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_thinking_config.py +0 -0
  581. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_train_context_preflight.py +0 -0
  582. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_training_controls.py +0 -0
  583. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_type_comment_prose.py +0 -0
  584. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_vast_api.py +0 -0
  585. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_vast_api_coverage.py +0 -0
  586. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_vast_offers.py +0 -0
  587. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_vast_provider_coverage.py +0 -0
  588. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_vast_runner.py +0 -0
  589. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_verified_revisions.py +0 -0
  590. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_verifiers.py +0 -0
  591. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_verl_checkpoint_export.py +0 -0
  592. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_verl_child_plugins.py +0 -0
  593. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_verl_silence_watchdog.py +0 -0
  594. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_version.py +0 -0
  595. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_vl_warmstart_adapter_keys.py +0 -0
  596. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_vram_architecture.py +0 -0
  597. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_wandb_link.py +0 -0
  598. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_wandb_naming.py +0 -0
  599. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_warmstart_adapter_download.py +0 -0
  600. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_warmstart_cross_repo.py +0 -0
  601. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_warmstart_error_attribution.py +0 -0
  602. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_warmstart_image_adapters.py +0 -0
  603. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_weight_cache.py +0 -0
  604. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_worker_dryrun.py +0 -0
  605. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_worker_hardexit.py +0 -0
  606. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_worker_image.py +0 -0
  607. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_worker_init_heartbeat.py +0 -0
  608. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_worker_stack.py +0 -0
  609. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_worker_thinking.py +0 -0
  610. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_workflow_contracts.py +0 -0
  611. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_workload_profile.py +0 -0
  612. {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/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.89
3
+ Version: 1.2.94
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
@@ -470,16 +470,10 @@ def _log_follow_progress(status: dict | None, fallback_state: str) -> tuple[str,
470
470
  parts = [state]
471
471
  heartbeat = status.get("last_heartbeat") if isinstance(status, dict) else None
472
472
  # retries rewind steps while state remains running, so surface the 0-based attempt identity.
473
- # prefer live `remote.attempt`; the heartbeat may belong to the superseded worker. fall back only
474
- # when `remote` is absent, not explicitly null: null marks the allocation window after teardown,
475
- # when the new attempt is unknown and the attached heartbeat is stale.
476
- from flash.providers._lifecycle.poll import _attempt_int
477
-
478
- remote = status.get("remote")
479
- remote_cleared = "remote" in status and remote is None
480
- attempt = _attempt_int(remote.get("attempt")) if isinstance(remote, dict) else None
481
- if attempt is None and not remote_cleared and isinstance(heartbeat, dict):
482
- attempt = _attempt_int(heartbeat.get("attempt"))
473
+ # `live_attempt` owns the provenance order (live `remote.attempt` first, heartbeat only when
474
+ # `remote` is absent rather than cleared at teardown) and is shared with the worker-artifact
475
+ # labelling below, so the spinner and the appended sections name the same current attempt.
476
+ attempt = render.live_attempt(status)
483
477
  if isinstance(heartbeat, dict):
484
478
  heartbeat_age_seconds = render._heartbeat_age_seconds(heartbeat.get("ts"))
485
479
  # stage and step come from the heartbeat, attempt from `remote` below. during the relaunch
@@ -712,20 +706,6 @@ def _follow_status(
712
706
  return 130
713
707
 
714
708
 
715
- def _print_worker_output(client: ApiClient, run_id: str, *, printed_any: bool = False) -> bool:
716
- for name, text in (client.get_worker_output(run_id) or {}).items():
717
- if not text:
718
- continue
719
- sep = "\n" if printed_any else ""
720
- if render.styled():
721
- print(f"{sep}{render.log_section(name)}")
722
- else:
723
- print(f"{sep}----- {name} -----")
724
- print(text, end="" if text.endswith("\n") else "\n")
725
- printed_any = True
726
- return printed_any
727
-
728
-
729
709
  def cmd_log(args) -> int:
730
710
  client = client_from_config()
731
711
  if getattr(args, "follow", False):
@@ -980,3 +960,10 @@ from flash.cli.commands.train_cost import ( # noqa: E402,F401
980
960
  _sft_cost_rows,
981
961
  _warn_if_wandb_requested_without_key,
982
962
  )
963
+
964
+ # re-exported so `commands._print_worker_output(...)` keeps resolving for `cmd_log` and the CLI tests.
965
+ from flash.cli.commands.worker_output import ( # noqa: E402,F401
966
+ _artifact_attempt,
967
+ _print_worker_output,
968
+ _worker_section_name,
969
+ )
@@ -0,0 +1,67 @@
1
+ """Printing the worker-uploaded text artifacts that `flash runs log` appends to a run log.
2
+
3
+ These sections are NOT part of the chronological log. `cmd_log` prints the control-plane log first
4
+ and appends these afterwards, so they always land at the tail no matter how old they are -- and the
5
+ plane returns the highest UPLOADED attempt, which during a retry is the attempt that just died, not
6
+ the one now running. Read without a label, the last thing on screen is a traceback from a worker
7
+ that has already been replaced.
8
+
9
+ So the job here is provenance: say which attempt produced each section, and say when that attempt is
10
+ not the live one. The old output is kept rather than hidden because it carries the failure that
11
+ explains why a retry exists at all.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import re
17
+ from typing import TYPE_CHECKING
18
+
19
+ from flash.cli.ui import render
20
+
21
+ if TYPE_CHECKING:
22
+ from flash.client import ApiClient
23
+
24
+
25
+ def _artifact_attempt(name: str) -> int | None:
26
+ """Return the bounded attempt encoded by a worker artifact name."""
27
+ from flash.providers._lifecycle.poll import _attempt_int
28
+
29
+ match = re.search(r"_attempt(\d+)\.txt$", name)
30
+ return _attempt_int(int(match.group(1))) if match else None
31
+
32
+
33
+ def _worker_section_name(name: str, current_attempt: int | None) -> str:
34
+ """Label an attempt-scoped artifact and identify superseded output."""
35
+ attempt = _artifact_attempt(name)
36
+ if attempt is None:
37
+ return name
38
+ if current_attempt is None:
39
+ return f"{name} (attempt={attempt})"
40
+ if attempt != current_attempt:
41
+ return f"{name} (attempt={attempt}, previous attempt; current attempt={current_attempt})"
42
+ return f"{name} (attempt={attempt}, current attempt)"
43
+
44
+
45
+ def _print_worker_output(client: ApiClient, run_id: str, *, printed_any: bool = False) -> bool:
46
+ worker_output = client.get_worker_output(run_id) or {}
47
+ if not worker_output:
48
+ return printed_any
49
+ try:
50
+ current_attempt = render.live_attempt(client.get_run(run_id) or {})
51
+ except Exception:
52
+ # artifact text is best-effort diagnostic output; a status refresh failure must not hide it.
53
+ current_attempt = None
54
+ for name, text in worker_output.items():
55
+ if not text:
56
+ continue
57
+ # label provenance from the filename rather than letting the final section, which is merely
58
+ # the last one appended, read as the live attempt's output.
59
+ section_name = _worker_section_name(name, current_attempt)
60
+ sep = "\n" if printed_any else ""
61
+ if render.styled():
62
+ print(f"{sep}{render.log_section(section_name)}")
63
+ else:
64
+ print(f"{sep}----- {section_name} -----")
65
+ print(text, end="" if text.endswith("\n") else "\n")
66
+ printed_any = True
67
+ return printed_any
@@ -43,6 +43,33 @@ _WARMUP_HEARTBEAT_FRESH_FOR_S = 1200.0
43
43
  _WARMUP_STAGES = frozenset({"rl_train_start", "rl_initializing"})
44
44
 
45
45
 
46
+ def live_attempt(obj: dict) -> int | None:
47
+ """The attempt a status payload says is live, or None when it cannot be established.
48
+
49
+ `remote.attempt` is the plane's live attempt. It is preferred over `last_heartbeat.attempt`,
50
+ which is whichever worker produced the ping and may already be superseded. The heartbeat is a
51
+ fallback only when `remote` is ABSENT: an explicitly null `remote` is the teardown window, where
52
+ the attached ping belongs to a worker that is already gone, so falling back there would report a
53
+ dead attempt as the live one.
54
+
55
+ Shared so the status line, the log-follow spinner, and worker-artifact labelling cannot disagree
56
+ about which attempt is current -- three surfaces that a user reads within one screen of each
57
+ other, where a disagreement reads as a run that is on two attempts at once.
58
+ """
59
+ from flash.providers._lifecycle.poll import _attempt_int
60
+
61
+ remote = obj.get("remote")
62
+ if isinstance(remote, dict):
63
+ attempt = _attempt_int(remote.get("attempt"))
64
+ if attempt is not None:
65
+ return attempt
66
+ elif "remote" in obj:
67
+ # explicitly null: the teardown window. the ping is the dead worker's, so there is no answer.
68
+ return None
69
+ heartbeat = obj.get("last_heartbeat")
70
+ return _attempt_int(heartbeat.get("attempt")) if isinstance(heartbeat, dict) else None
71
+
72
+
46
73
  def heartbeat_is_current_attempt(obj: dict, heartbeat: dict) -> bool:
47
74
  """False only when the heartbeat provably belongs to a superseded retry attempt.
48
75
 
@@ -808,6 +808,7 @@ from flash.cli.ui.heartbeat import ( # noqa: E402,F401
808
808
  _superseded_hint,
809
809
  heartbeat_is_current_attempt,
810
810
  heartbeat_is_superseded,
811
+ live_attempt,
811
812
  warmup_message,
812
813
  )
813
814
  from flash.cli.ui.tables import ( # noqa: E402,F401
@@ -19,6 +19,10 @@ _KV_BLOCK_TOKENS = 16
19
19
  # floor remains authoritative at short context; longer contexts retain 1.5 gb plus 25% fragmentation.
20
20
  _KV_PROFILE_OVERHEAD_GB = 1.5
21
21
  _KV_FRAGMENTATION_MARGIN = 1.25
22
+ # the smallest share of a card vllm is given. below this the engine has no room for its own runtime
23
+ # once the kv pool is carved out, so a budget that prices under it is not a smaller engine but a
24
+ # broken one. the legacy equation and the multi-rank shard path both bottom out here.
25
+ _MIN_ENGINE_UTIL = 0.10
22
26
 
23
27
 
24
28
  def _round_up(value: int, multiple: int) -> int:
@@ -138,15 +142,18 @@ def colocate_kv_util(
138
142
  fp8_kv: bool = False,
139
143
  model_info=None,
140
144
  preserve_legacy_floor: bool = False,
145
+ tensor_parallel: int = 1,
141
146
  ) -> float:
142
- """vllm_gpu_memory_utilization for the colocated GRPO rollout engine.
147
+ """vllm_gpu_memory_utilization for one colocated rollout tensor-parallel rank.
143
148
 
144
- Budget vLLM's weight copy plus KV cache. Catalog models use geometry with measured overhead
145
- and an 8 GB floor; uncataloged models retain the conservative legacy equation.
149
+ Budget the rank's weight shard plus a conservative full KV cache. Catalog models use geometry
150
+ with measured overhead and an 8 GB floor; uncataloged models retain the legacy KV equation.
146
151
  """
147
- weights_gb = (
148
- max(0.5, float(params_b or 1.0)) * 2.0
149
- ) # vLLM's bf16 weight copy lives in the budget
152
+ total_weights_gb = max(0.5, float(params_b or 1.0)) * 2.0
153
+ tp_size = max(1, int(tensor_parallel))
154
+ # tensor parallelism shards vllm's bf16 weights, but kv heads can replicate when tp is wider than
155
+ # the model's kv-head count. shard only the weight term and keep the full kv budget on every rank.
156
+ weights_gb = total_weights_gb if tp_size == 1 else total_weights_gb / tp_size
150
157
  # catalog geometry is authoritative. active params remain only for the uncataloged fallback, while
151
158
  # the weight copy always uses total parameters.
152
159
  kv_params_b = float(active_params_b) if active_params_b else params_b
@@ -169,7 +176,7 @@ def colocate_kv_util(
169
176
  preserve_legacy_floor=preserve_legacy_floor,
170
177
  ),
171
178
  )
172
- return max(0.10, min(_util_cap, (weights_gb + kv_gb) / max(1.0, total_vram_gb)))
179
+ return max(_MIN_ENGINE_UTIL, min(_util_cap, (weights_gb + kv_gb) / max(1.0, total_vram_gb)))
173
180
  # Sleep mode keeps a larger pool (1.5x margin): the engine is offloaded during the backward, so a
174
181
  # bigger rollout-phase KV does not compete with the training peak.
175
182
  kv_pool_gb = max(
@@ -184,4 +191,9 @@ def colocate_kv_util(
184
191
  preserve_legacy_floor=preserve_legacy_floor,
185
192
  ),
186
193
  )
187
- return min(_util_cap, (weights_gb + kv_pool_gb) / max(1.0, total_vram_gb))
194
+ sized = min(_util_cap, (weights_gb + kv_pool_gb) / max(1.0, total_vram_gb))
195
+ # sharding the weight term can drive a small model's rank budget low enough that vllm has no
196
+ # room left for its own runtime once the kv pool is carved out -- a 4B model on 2 cards prices
197
+ # under this floor. single-rank sizing carries the whole weight copy and never gets that small,
198
+ # so the floor exists only where sharding created the problem.
199
+ return max(_MIN_ENGINE_UTIL, sized) if tp_size > 1 else sized
@@ -374,7 +374,7 @@ def run_opd_train(spec=None) -> None:
374
374
  # and on an image run that fan-out exhausted the grpo worker container's threads.
375
375
  "multimodal": bool(multimodal),
376
376
  "gpu_mem_util": _resolve_opd_gpu_mem_util(
377
- request, prompt_state, runtime, model_id, fp8_kv
377
+ request, prompt_state, workload, runtime, model_id, fp8_kv
378
378
  ),
379
379
  "loggers": runtime.loggers,
380
380
  # resolved from the out-of-process capability probe, never by opening cuda in this parent -- see fused_ce_backend.
@@ -535,6 +535,7 @@ def _spec_gpu_type(spec: Any) -> str:
535
535
  def _resolve_opd_gpu_mem_util(
536
536
  request: _OpdRequest,
537
537
  prompt_state: _PromptState,
538
+ workload: _WorkloadState,
538
539
  runtime: _RuntimeState,
539
540
  model_id: str,
540
541
  fp8_kv: bool,
@@ -559,12 +560,15 @@ def _resolve_opd_gpu_mem_util(
559
560
  "model_id": model_id,
560
561
  "model_revision": str(getattr(request, "model_revision", "") or ""),
561
562
  "engine_len": int(prompt_state.max_model_len),
562
- "group_size": int(request.knobs.group_size),
563
+ # opd submits prompts_per_step * group_size generations to the rollout engine together.
564
+ # grpo's concurrency is group_size because its resolver receives one prompt group here.
565
+ "group_size": int(workload.prompts_per_step) * int(request.knobs.group_size),
563
566
  },
564
567
  gpu_type=_spec_gpu_type(getattr(request, "spec", None)),
565
568
  n_gpus=int(runtime.gpu_count),
566
569
  fp8_kv=bool(fp8_kv),
567
570
  sleep_unsupported=rollout_sleep_unsupported(model_id),
571
+ preserve_legacy_floor=True,
568
572
  )
569
573
 
570
574
 
@@ -499,24 +499,28 @@ def resolve_gpu_mem_util(
499
499
  n_gpus: int,
500
500
  fp8_kv: bool,
501
501
  sleep_unsupported: bool,
502
+ preserve_legacy_floor: bool = False,
502
503
  ) -> float:
503
504
  """size vllm's colocated executor budget from this run's geometry.
504
505
 
505
506
  ``gpu_memory_utilization`` covers the second bf16 weight copy plus kv pool. using
506
507
  ``colocate_kv_util`` keeps worker allocation aligned with preflight admission.
507
508
 
508
- the flat constant is kept where the model does NOT apply, because a wrong number is worse than
509
+ for multi-gpu runs, vllm shards its bf16 weight copy across tensor-parallel ranks. the kv term
510
+ remains unsharded here because vllm can replicate kv heads when tensor parallelism is wider than
511
+ the model's kv-head count. the result is explicitly capped at the old 0.5 constant, so this path
512
+ can only lower a rank's reservation and cannot create a new over-reservation.
513
+
514
+ the flat constant is kept where the model does not apply, because a wrong number is worse than
509
515
  a conservative one:
510
516
 
511
- - UNKNOWN CARD (empty/unmanaged ``gpu.type``): the budget is a fraction of the card, so without
517
+ - unknown card (empty/unmanaged ``gpu.type``): the budget is a fraction of the card, so without
512
518
  its size there is nothing to take a fraction of.
513
- - MULTI-GPU (``n_gpus > 1``): the rollout is tensor-parallel, so vLLM's weight copy is sharded
514
- ACROSS cards while ``colocate_kv_util`` sizes one whole copy against one card. a single-card
515
- number would over-reserve per rank on exactly the shapes already tight.
516
- - PINNED REVISION with no resolvable parameter count: the weight term dominates, so a guessed
519
+ - pinned revision with no resolvable parameter count: the weight term dominates, so a guessed
517
520
  size is not worth acting on.
521
+ - any sizing exception: launch falls back to the previous constant instead of failing.
518
522
  """
519
- if n_gpus > 1 or not (gpu_type or "").strip():
523
+ if not (gpu_type or "").strip():
520
524
  return _DEFAULT_GPU_MEM_UTIL
521
525
  try:
522
526
  from flash.core.catalog import MODELS
@@ -545,7 +549,7 @@ def resolve_gpu_mem_util(
545
549
  )
546
550
  if params_b <= 0:
547
551
  return _DEFAULT_GPU_MEM_UTIL
548
- return colocate_kv_util(
552
+ sized = colocate_kv_util(
549
553
  params_b,
550
554
  int(inp["engine_len"]),
551
555
  total_vram_gb,
@@ -558,7 +562,12 @@ def resolve_gpu_mem_util(
558
562
  active_params_b=float(getattr(info, "active_params_b", 0.0) or 0.0) or None,
559
563
  fp8_kv=fp8_kv,
560
564
  model_info=info,
565
+ preserve_legacy_floor=preserve_legacy_floor,
566
+ tensor_parallel=n_gpus,
561
567
  )
568
+ # multi-rank sizing is strictly one-directional against the previous worker contract: it may
569
+ # free memory but can never claim more than the flat reservation a working run already used.
570
+ return min(_DEFAULT_GPU_MEM_UTIL, sized) if n_gpus > 1 else sized
562
571
  except Exception as e: # sizing must never be what stops a run from launching
563
572
  print(
564
573
  f"[rl-verl] gpu_memory_utilization sizing failed ({e}); using {_DEFAULT_GPU_MEM_UTIL}"
@@ -224,6 +224,9 @@ def _format_child_tail(tail: object, silent_ticks: object = None) -> str:
224
224
 
225
225
  def _format_heartbeat(hb: dict) -> str:
226
226
  msg = f"worker: stage={hb.get('stage')}"
227
+ attempt = _attempt_int(hb.get("attempt"))
228
+ if attempt is not None:
229
+ msg += f" attempt={attempt}"
227
230
  if hb.get("liveness"):
228
231
  msg += " liveness=true"
229
232
  for key, digits in (
@@ -428,9 +428,10 @@ def _deferred_resubmit_loop(spec) -> None:
428
428
  def _latest_worker_artifact_name(repo: str, prefix: str, phase: str, kind: str) -> str:
429
429
  """Return the newest worker artifact under a prefix.
430
430
 
431
- Console uses one overwritten name; errors and raylogs use the highest attempt. Fall back when
432
- listing fails, and derive attempt-scoped names from the writer's definition to prevent silent
433
- reader/writer drift.
431
+ Attempt-scoped console and error artifacts use the highest uploaded attempt, which can still be
432
+ older than the live attempt while its replacement has not uploaded yet. Console falls back to its
433
+ canonical final name and errors to attempt 0 when listing fails; derive scoped names from the
434
+ writer's definition to prevent silent reader/writer drift.
434
435
  """
435
436
  import re
436
437
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "freesolo-flash-dev"
3
- version = "1.2.89"
3
+ version = "1.2.94"
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.89"
140
+ version = "1.2.94"
141
141
 
142
142
  [tool.pytest.ini_options]
143
143
  pythonpath = ["."]
@@ -1429,6 +1429,60 @@ def test_status_runs_and_log_command(fake_client, capsys, monkeypatch) -> None:
1429
1429
  assert "cost_usd" not in out
1430
1430
 
1431
1431
 
1432
+ def test_log_labels_previous_attempt_artifacts_after_the_live_attempt_log(
1433
+ fake_client, capsys, monkeypatch
1434
+ ) -> None:
1435
+ live_heartbeat = {
1436
+ "stage": "rl_step",
1437
+ "step": 4,
1438
+ "ts": 456.0,
1439
+ "attempt": 1,
1440
+ "gpu": {"device_name": "NVIDIA B200"},
1441
+ }
1442
+ fake_client.log_text = _format_heartbeat(live_heartbeat) + "\n"
1443
+ monkeypatch.setattr(
1444
+ fake_client,
1445
+ "get_run",
1446
+ lambda _run_id: {
1447
+ "run_id": "flash-1",
1448
+ "state": "running",
1449
+ "remote": {"attempt": 1},
1450
+ "last_heartbeat": live_heartbeat,
1451
+ },
1452
+ )
1453
+ monkeypatch.setattr(
1454
+ fake_client,
1455
+ "get_worker_output",
1456
+ lambda _run_id: {
1457
+ "console_rl_attempt0.txt": (
1458
+ 'HEARTBEAT {"stage":"rl_step","step":0,"attempt":0,'
1459
+ '"gpu":{"device_name":"NVIDIA H200"}}\n'
1460
+ ),
1461
+ "error_rl_attempt0.txt": "torch.OutOfMemoryError: CUDA OOM\n",
1462
+ "raylogs_rl_attempt0.txt": "raylet exited\n",
1463
+ },
1464
+ )
1465
+
1466
+ assert _run(["runs", "log", "flash-1"]) == 0
1467
+ out = capsys.readouterr().out
1468
+
1469
+ live_line = "worker: stage=rl_step attempt=1 step=4"
1470
+ previous_header = (
1471
+ "----- console_rl_attempt0.txt (attempt=0, previous attempt; current attempt=1) -----"
1472
+ )
1473
+ assert live_line in out
1474
+ assert previous_header in out
1475
+ assert (
1476
+ "----- error_rl_attempt0.txt (attempt=0, previous attempt; current attempt=1) -----" in out
1477
+ )
1478
+ assert (
1479
+ "----- raylogs_rl_attempt0.txt (attempt=0, previous attempt; current attempt=1) -----"
1480
+ in out
1481
+ )
1482
+ assert out.index(live_line) < out.index(previous_header)
1483
+ assert 'HEARTBEAT {"stage":"rl_step","step":0,"attempt":0' in out
1484
+
1485
+
1432
1486
  def test_log_prints_partial_log_line_with_newline(fake_client, capsys) -> None:
1433
1487
  fake_client.log_text = "partial log line"
1434
1488
  fake_client.get_worker_output = lambda run_id: {}
@@ -671,6 +671,30 @@ def test_heartbeat_is_current_attempt_rejects_malformed_identities() -> None:
671
671
  assert is_current({"remote": {"attempt": 2}}, {"attempt": 1}) is False
672
672
 
673
673
 
674
+ def test_live_attempt_is_one_rule_for_every_surface_that_names_an_attempt() -> None:
675
+ """The spinner, the status line, and the worker-artifact labels must not disagree.
676
+
677
+ They are read within one screen of each other, so two provenance rules read as a run that is on
678
+ two attempts at once -- and the artifact labels would call the live attempt's console "previous".
679
+ """
680
+ live = render.live_attempt
681
+
682
+ # the plane's live attempt wins over the ping, which may be the superseded worker's.
683
+ assert live({"remote": {"attempt": 2}, "last_heartbeat": {"attempt": 1}}) == 2
684
+ # `remote` absent entirely (a managed payload that omits it): the ping is all there is.
685
+ assert live({"last_heartbeat": {"attempt": 3}}) == 3
686
+ # a `remote` that carries no usable attempt is not an answer either, so the ping still applies.
687
+ assert live({"remote": {}, "last_heartbeat": {"attempt": 1}}) == 1
688
+ for bad in ["1", True, 2.7, float("inf"), -1]:
689
+ assert live({"remote": {"attempt": bad}, "last_heartbeat": {"attempt": 4}}) == 4
690
+ # explicitly null `remote` is the teardown window: the attached ping belongs to a dead worker,
691
+ # so there is no live attempt to report rather than that worker's.
692
+ assert live({"remote": None, "last_heartbeat": {"attempt": 1}}) is None
693
+ # nothing usable anywhere reads as unknown, never as attempt 0.
694
+ assert live({}) is None
695
+ assert live({"last_heartbeat": {"attempt": "1"}}) is None
696
+
697
+
674
698
  def test_progress_age_always_adds_to_heartbeat_age(monkeypatch):
675
699
  from flash.cli.ui import heartbeat as heartbeat_ui
676
700
  from flash.cli.ui import render
@@ -479,7 +479,7 @@ def test_surface_heartbeat_logs_gpu_status(monkeypatch):
479
479
  assert stage == "sft_step"
480
480
  assert len(lines) == 1
481
481
  line = lines[0]
482
- assert "worker: stage=sft_step step=12 loss=1.2346" in line
482
+ assert "worker: stage=sft_step attempt=0 step=12 loss=1.2346" in line
483
483
  assert "gpu[RTX 5090" in line
484
484
  assert "util=97%" in line
485
485
  assert "mem=22.2GB/31.8GB" in line
@@ -9164,6 +9164,38 @@ def test_normalize_initial_prompt_rejects_a_state_with_no_prompt():
9164
9164
  normalize_initial_prompt(_Prompt(), state, None)
9165
9165
 
9166
9166
 
9167
+ def test_opd_multigpu_gpu_mem_util_matches_the_shared_tp_aware_resolver():
9168
+ request = SimpleNamespace(
9169
+ model_revision="",
9170
+ knobs=SimpleNamespace(group_size=4),
9171
+ spec=SimpleNamespace(gpu=SimpleNamespace(type="H200")),
9172
+ )
9173
+ prompt_state = SimpleNamespace(max_model_len=2048)
9174
+ workload = SimpleNamespace(prompts_per_step=2)
9175
+ runtime = SimpleNamespace(gpu_count=2)
9176
+ model_id = "Qwen/Qwen3.6-35B-A3B"
9177
+
9178
+ got = opd_train._resolve_opd_gpu_mem_util(
9179
+ request, prompt_state, workload, runtime, model_id, fp8_kv=False
9180
+ )
9181
+ want = rl_train.resolve_gpu_mem_util(
9182
+ {
9183
+ "model_id": model_id,
9184
+ "model_revision": "",
9185
+ "engine_len": 2048,
9186
+ "group_size": 8,
9187
+ },
9188
+ gpu_type="H200",
9189
+ n_gpus=2,
9190
+ fp8_kv=False,
9191
+ sleep_unsupported=True,
9192
+ preserve_legacy_floor=True,
9193
+ )
9194
+
9195
+ assert got == want
9196
+ assert got < rl_train._DEFAULT_GPU_MEM_UTIL
9197
+
9198
+
9167
9199
  def test_build_opd_overrides_sizes_the_rollout_memory_budget():
9168
9200
  # opd emitted no gpu_memory_utilization at all, so verl substituted its own default of 0.5 and
9169
9201
  # the engine claimed half the CARD on every wake regardless of what the trainer held. this is
@@ -1132,6 +1132,7 @@ def test_a_retry_marks_where_the_previous_attempt_ends_in_the_log(orch, monkeypa
1132
1132
  if attempt == 0:
1133
1133
  print("Traceback (most recent call last):\ntorch.OutOfMemoryError: CUDA OOM", file=log)
1134
1134
  return PollResult(False, failure="stalled", detail="infra")
1135
+ print("worker: stage=rl_step attempt=1 step=1", file=log)
1135
1136
  return PollResult(True, metrics={"train_tokens": 4096})
1136
1137
 
1137
1138
  monkeypatch.setattr(rp_jobs, "submit_run", fake_submit)
@@ -1147,6 +1148,9 @@ def test_a_retry_marks_where_the_previous_attempt_ends_in_the_log(orch, monkeypa
1147
1148
  assert text.index("CUDA OOM") < text.index(marker), (
1148
1149
  "the marker must sit after the failure it disowns, or it cannot separate the two attempts"
1149
1150
  )
1151
+ assert text.index(marker) < text.index("worker: stage=rl_step attempt=1 step=1"), (
1152
+ "the replacement attempt's heartbeat must follow the boundary that assigns its provenance"
1153
+ )
1150
1154
 
1151
1155
 
1152
1156
  def test_the_marker_does_not_claim_one_previous_attempt_after_two_failures(orch, monkeypatch):
@@ -1730,7 +1730,19 @@ def test_gpu_mem_util_is_the_sized_budget_not_a_constant():
1730
1730
  got = rl_train.resolve_gpu_mem_util(
1731
1731
  _mem_util_inp(), gpu_type="H100", n_gpus=1, fp8_kv=False, sleep_unsupported=False
1732
1732
  )
1733
- assert got == want
1733
+ explicit_tp_one = colocate_kv_util(
1734
+ float(info.params_b),
1735
+ 2048,
1736
+ float(get_gpu_info("H100").vram_gb),
1737
+ sleep_mode=True,
1738
+ num_generations=8,
1739
+ active_params_b=None,
1740
+ fp8_kv=False,
1741
+ model_info=info,
1742
+ tensor_parallel=1,
1743
+ )
1744
+ assert got == want == explicit_tp_one
1745
+ assert got.hex() == "0x1.11eb851eb851ep-2"
1734
1746
  # and it is genuinely NOT the old constant, so the test cannot pass on an unwired build.
1735
1747
  assert got != rl_train._DEFAULT_GPU_MEM_UTIL
1736
1748
  assert got < rl_train._DEFAULT_GPU_MEM_UTIL
@@ -1791,22 +1803,49 @@ def test_gpu_mem_util_sizing_reaches_the_launch_config():
1791
1803
  )
1792
1804
 
1793
1805
 
1794
- def test_gpu_mem_util_keeps_the_constant_where_the_model_does_not_apply():
1795
- """The three shapes ``colocate_kv_util`` cannot size are left on the conservative constant.
1796
-
1797
- Multi-gpu is the load-bearing one: the rollout is tensor-parallel, so vLLM's weight copy is
1798
- sharded ACROSS cards while the model sizes one whole copy against ONE card. Sizing it here would
1799
- over-reserve per rank on exactly the shapes that are already tight.
1800
- """
1806
+ def test_multigpu_gpu_mem_util_shards_only_weights_and_frees_the_observed_shortfall():
1801
1807
  default = rl_train._DEFAULT_GPU_MEM_UTIL
1802
- # multi-gpu: sharded rollout, unmodelled.
1803
- assert (
1804
- rl_train.resolve_gpu_mem_util(
1805
- _mem_util_inp(), gpu_type="H100", n_gpus=2, fp8_kv=False, sleep_unsupported=False
1808
+ inp = _mem_util_inp(model_id="Qwen/Qwen3.6-35B-A3B", group_size=4)
1809
+ for gpu_type, vram_gb in (("H200", 141.0), ("B200", 180.0)):
1810
+ got = rl_train.resolve_gpu_mem_util(
1811
+ inp, gpu_type=gpu_type, n_gpus=2, fp8_kv=False, sleep_unsupported=True
1806
1812
  )
1807
- == default
1808
- )
1809
- # unknown card: the budget is a FRACTION of the card, so there is nothing to take a fraction of.
1813
+ assert got < default
1814
+ assert (default - got) * vram_gb > 1.57
1815
+
1816
+
1817
+ def test_multigpu_gpu_mem_util_never_exceeds_the_previous_constant():
1818
+ default = rl_train._DEFAULT_GPU_MEM_UTIL
1819
+ model_ids = ("Qwen/Qwen3.5-0.8B", "Qwen/Qwen3.5-4B", "Qwen/Qwen3.6-35B-A3B")
1820
+ for model_id in model_ids:
1821
+ for gpu_type in ("H100", "H200", "B200"):
1822
+ for tensor_parallel in (2, 4, 8):
1823
+ for engine_len in (1024, 2048, 8192, 32768):
1824
+ for group_size in (2, 4, 8):
1825
+ got = rl_train.resolve_gpu_mem_util(
1826
+ _mem_util_inp(
1827
+ model_id=model_id,
1828
+ engine_len=engine_len,
1829
+ group_size=group_size,
1830
+ ),
1831
+ gpu_type=gpu_type,
1832
+ n_gpus=tensor_parallel,
1833
+ fp8_kv=False,
1834
+ sleep_unsupported=True,
1835
+ )
1836
+ assert 0.10 <= got <= default, (
1837
+ model_id,
1838
+ gpu_type,
1839
+ tensor_parallel,
1840
+ engine_len,
1841
+ group_size,
1842
+ got,
1843
+ )
1844
+
1845
+
1846
+ def test_gpu_mem_util_keeps_the_constant_where_the_model_does_not_apply(monkeypatch):
1847
+ default = rl_train._DEFAULT_GPU_MEM_UTIL
1848
+ # unknown card: the budget is a fraction of the card, so there is nothing to take a fraction of.
1810
1849
  for unknown in ("", " ", "Nonexistent9000"):
1811
1850
  assert (
1812
1851
  rl_train.resolve_gpu_mem_util(
@@ -1815,9 +1854,13 @@ def test_gpu_mem_util_keeps_the_constant_where_the_model_does_not_apply():
1815
1854
  == default
1816
1855
  )
1817
1856
  # unresolvable model size: the weight copy is the dominant term.
1857
+ monkeypatch.setattr("flash.engine.plan.vram.resolve_params_b", lambda *_args, **_kwargs: None)
1818
1858
  assert (
1819
1859
  rl_train.resolve_gpu_mem_util(
1820
- _mem_util_inp(model_id="not-a-real-org/not-a-real-model-xyz"),
1860
+ _mem_util_inp(
1861
+ model_id="Qwen/Qwen3.5-4B",
1862
+ model_revision="a" * 40,
1863
+ ),
1821
1864
  gpu_type="H100",
1822
1865
  n_gpus=1,
1823
1866
  fp8_kv=False,
@@ -1825,6 +1868,14 @@ def test_gpu_mem_util_keeps_the_constant_where_the_model_does_not_apply():
1825
1868
  )
1826
1869
  == default
1827
1870
  )
1871
+ # any sizing exception keeps launch on the prior constant rather than making sizing fatal.
1872
+ monkeypatch.setattr("flash.providers.base.get_gpu_info", lambda _gpu_type: 1 / 0)
1873
+ assert (
1874
+ rl_train.resolve_gpu_mem_util(
1875
+ _mem_util_inp(), gpu_type="H100", n_gpus=2, fp8_kv=False, sleep_unsupported=False
1876
+ )
1877
+ == default
1878
+ )
1828
1879
 
1829
1880
 
1830
1881
  def test_gpu_mem_util_does_not_credit_an_offload_a_resident_engine_never_takes():