freesolo-flash-dev 1.2.37__tar.gz → 1.2.43__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 (547) hide show
  1. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/PKG-INFO +1 -1
  2. freesolo_flash_dev-1.2.43/flash/adapters/fused_experts.py +375 -0
  3. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/core/catalog.py +7 -3
  4. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/__init__.py +3 -3
  5. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/backend_common.py +51 -65
  6. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/model/adapter.py +15 -20
  7. freesolo_flash_dev-1.2.43/flash/engine/worker/model/lora.py +157 -0
  8. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/sft_train.py +3 -2
  9. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/opd/failures.py +4 -0
  10. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/rl/checkpoints.py +7 -1
  11. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/rl/inputs.py +1 -1
  12. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/sft/checkpoints.py +18 -1
  13. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/verl/checkpoints.py +158 -57
  14. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/preparation.py +3 -1
  15. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/pyproject.toml +2 -2
  16. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_adapter_shard_completeness.py +95 -4
  17. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_backend_common.py +2 -2
  18. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_disk_gb.py +90 -16
  19. freesolo_flash_dev-1.2.43/tests/test_fused_expert_warmstart.py +651 -0
  20. freesolo_flash_dev-1.2.43/tests/test_lora_rank_preflight.py +623 -0
  21. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_sft_train.py +100 -226
  22. freesolo_flash_dev-1.2.43/tests/test_verl_checkpoint_export.py +495 -0
  23. freesolo_flash_dev-1.2.43/tests/test_vl_warmstart_adapter_keys.py +161 -0
  24. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_warmstart_adapter_download.py +10 -12
  25. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_warmstart_cross_repo.py +1 -1
  26. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_worker_stack.py +11 -15
  27. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/uv.lock +1 -1
  28. freesolo_flash_dev-1.2.37/flash/engine/worker/model/lora.py +0 -118
  29. freesolo_flash_dev-1.2.37/tests/test_lora_rank_preflight.py +0 -311
  30. freesolo_flash_dev-1.2.37/tests/test_vl_warmstart_adapter_keys.py +0 -83
  31. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/.dockerignore +0 -0
  32. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/.env.example +0 -0
  33. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/.github/CODEOWNERS +0 -0
  34. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  35. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  36. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  37. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  38. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/.github/dependabot.yml +0 -0
  39. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/.github/workflows/auto-rebake.yml +0 -0
  40. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/.github/workflows/bake-kernel-cache.yml +0 -0
  41. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/.github/workflows/ci.yml +0 -0
  42. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/.github/workflows/main-source-guard.yml +0 -0
  43. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/.github/workflows/notify-tests-repo.yml +0 -0
  44. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/.github/workflows/publish-dev.yml +0 -0
  45. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/.github/workflows/publish-image.yml +0 -0
  46. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/.github/workflows/publish.yml +0 -0
  47. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/.github/workflows/version-parity.yml +0 -0
  48. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/.github/workflows/worker-image.yml +0 -0
  49. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/.gitignore +0 -0
  50. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/CHANGELOG.md +0 -0
  51. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/CODE_OF_CONDUCT.md +0 -0
  52. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/CONTRIBUTING.md +0 -0
  53. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/Dockerfile +0 -0
  54. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/Dockerfile.worker +0 -0
  55. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/LICENSE +0 -0
  56. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/NOTICE +0 -0
  57. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/README.md +0 -0
  58. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/SECURITY.md +0 -0
  59. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/SELF_HOSTING.md +0 -0
  60. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/build/kernel_cache/.gitignore +0 -0
  61. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/build/kernel_cache/.keep +0 -0
  62. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/deploy/infisical/README.md +0 -0
  63. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/deploy/infisical/entrypoint.sh +0 -0
  64. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/docker/Dockerfile.kernelcache +0 -0
  65. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/docker/Dockerfile.kernelcache.relayer +0 -0
  66. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/docker/bake_kernel_cache.py +0 -0
  67. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/docker/bake_pod_entry.py +0 -0
  68. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/docker/extract_cudart_fix.py +0 -0
  69. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/docker/kernel_fingerprint.py +0 -0
  70. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/docker/make_rp_handler.py +0 -0
  71. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/__init__.py +0 -0
  72. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/_internal/__init__.py +0 -0
  73. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/_internal/channel.py +0 -0
  74. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/_internal/diagnostics.py +0 -0
  75. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/_internal/fileio.py +0 -0
  76. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/_internal/logging.py +0 -0
  77. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/_internal/paths.py +0 -0
  78. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/adapters/__init__.py +0 -0
  79. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/adapters/artifacts.py +0 -0
  80. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/adapters/lora_rank.py +0 -0
  81. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/__init__.py +0 -0
  82. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/__main__.py +0 -0
  83. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/commands/__init__.py +0 -0
  84. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/commands/deploy.py +0 -0
  85. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/commands/env/__init__.py +0 -0
  86. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/commands/env/episode.py +0 -0
  87. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/commands/env/eval.py +0 -0
  88. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/commands/env/eval_args.py +0 -0
  89. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/commands/env/imports.py +0 -0
  90. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/commands/env/list.py +0 -0
  91. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/commands/env/push.py +0 -0
  92. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/commands/env/retained.py +0 -0
  93. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/commands/env/setup.py +0 -0
  94. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/commands/env/test.py +0 -0
  95. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/commands/env/test_evaluations.py +0 -0
  96. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/commands/env/test_params.py +0 -0
  97. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/commands/env/test_warnings.py +0 -0
  98. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/commands/prompt_budget.py +0 -0
  99. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/commands/traces.py +0 -0
  100. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/commands/train_cost.py +0 -0
  101. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/scaffold/TRAINING.md +0 -0
  102. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/scaffold/__init__.py +0 -0
  103. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/ui/__init__.py +0 -0
  104. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/ui/cost.py +0 -0
  105. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/ui/env_panels.py +0 -0
  106. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/ui/heartbeat.py +0 -0
  107. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/ui/render.py +0 -0
  108. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/ui/tables.py +0 -0
  109. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cli/ui/tty.py +0 -0
  110. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/client/__init__.py +0 -0
  111. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/client/config.py +0 -0
  112. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/client/freesolo_api.py +0 -0
  113. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/client/http.py +0 -0
  114. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/client/runtime_secrets.py +0 -0
  115. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/client/shapes.py +0 -0
  116. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/client/specs.py +0 -0
  117. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/client/streaming.py +0 -0
  118. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/content/__init__.py +0 -0
  119. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/content/multimodal.py +0 -0
  120. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/content/structured_outputs.py +0 -0
  121. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/content/thinking.py +0 -0
  122. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/core/__init__.py +0 -0
  123. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/core/spec.py +0 -0
  124. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cost/__init__.py +0 -0
  125. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cost/analytical.py +0 -0
  126. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cost/facts.py +0 -0
  127. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cost/spec.py +0 -0
  128. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/cost/types.py +0 -0
  129. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/__init__.py +0 -0
  130. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/plan/__init__.py +0 -0
  131. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/plan/kv_sizing.py +0 -0
  132. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/plan/model_config_probe.py +0 -0
  133. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/plan/prompt_budget.py +0 -0
  134. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/plan/recipe.py +0 -0
  135. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/plan/steps.py +0 -0
  136. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/plan/vram.py +0 -0
  137. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/profiling/__init__.py +0 -0
  138. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/profiling/dataset_profile.py +0 -0
  139. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/profiling/reasoning_render.py +0 -0
  140. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/profiling/sft_workload.py +0 -0
  141. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/profiling/tokenizer.py +0 -0
  142. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/profiling/workload_profile.py +0 -0
  143. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/result/__init__.py +0 -0
  144. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/result/accounting.py +0 -0
  145. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/result/rollout_samples.py +0 -0
  146. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/__main__.py +0 -0
  147. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/entry/__init__.py +0 -0
  148. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/entry/opd.py +0 -0
  149. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/entry/rl.py +0 -0
  150. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/entry/sft.py +0 -0
  151. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/io/__init__.py +0 -0
  152. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/io/heartbeat.py +0 -0
  153. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/io/hf.py +0 -0
  154. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/io/prefetch.py +0 -0
  155. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/io/wandb_log.py +0 -0
  156. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/model/__init__.py +0 -0
  157. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/model/decoding.py +0 -0
  158. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/model/packing.py +0 -0
  159. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/opd_train.py +0 -0
  160. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/opd_train_runner.py +0 -0
  161. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/perf/__init__.py +0 -0
  162. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/perf/diagnostics.py +0 -0
  163. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/perf/lifecycle.py +0 -0
  164. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/perf/liger.py +0 -0
  165. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/perf/memory.py +0 -0
  166. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/rl_train.py +0 -0
  167. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/rl_train_runner.py +0 -0
  168. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/runtime/__init__.py +0 -0
  169. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
  170. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
  171. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/runtime/rng.py +0 -0
  172. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/score_batcher.py +0 -0
  173. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/sft_train_runner.py +0 -0
  174. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/teacher/__init__.py +0 -0
  175. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/teacher/client.py +0 -0
  176. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/teacher/encoding.py +0 -0
  177. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
  178. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/__init__.py +0 -0
  179. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/core/__init__.py +0 -0
  180. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/core/child/__init__.py +0 -0
  181. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/core/child/glue.py +0 -0
  182. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/core/step_timing.py +0 -0
  183. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/finalize.py +0 -0
  184. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/opd/__init__.py +0 -0
  185. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/opd/batching.py +0 -0
  186. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/opd/bridge.py +0 -0
  187. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/opd/child/__init__.py +0 -0
  188. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/opd/child/bridge.py +0 -0
  189. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/opd/child/multiturn.py +0 -0
  190. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/opd/child/plugin.py +0 -0
  191. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/opd/child/structured.py +0 -0
  192. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/opd/gkd.py +0 -0
  193. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
  194. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/opd/overrides.py +0 -0
  195. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/opd/prompts.py +0 -0
  196. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/opd/reporting.py +0 -0
  197. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/opd/scoring.py +0 -0
  198. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/opd/state.py +0 -0
  199. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/opd/validation.py +0 -0
  200. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/rl/__init__.py +0 -0
  201. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/rl/child/__init__.py +0 -0
  202. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/rl/child/multiturn.py +0 -0
  203. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/rl/child/plugin.py +0 -0
  204. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/rl/config.py +0 -0
  205. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/rl/multi_turn.py +0 -0
  206. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/rl/scoring.py +0 -0
  207. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/rl/shims.py +0 -0
  208. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/rl/single_turn.py +0 -0
  209. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/rl/verl_config.py +0 -0
  210. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/sft/__init__.py +0 -0
  211. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/train/sft/config.py +0 -0
  212. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/verl/__init__.py +0 -0
  213. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/verl/capabilities.py +0 -0
  214. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/verl/child_io.py +0 -0
  215. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/verl/diagnostics.py +0 -0
  216. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker/verl/parallelism.py +0 -0
  217. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/engine/worker_entrypoint.py +0 -0
  218. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/envs/__init__.py +0 -0
  219. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/envs/adapter.py +0 -0
  220. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/envs/base.py +0 -0
  221. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/envs/cache_security.py +0 -0
  222. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/envs/dataset_selection.py +0 -0
  223. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/envs/evaluations.py +0 -0
  224. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/envs/identity.py +0 -0
  225. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/envs/loader.py +0 -0
  226. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/envs/namespace_listing.py +0 -0
  227. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/envs/package/__init__.py +0 -0
  228. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/envs/package/limits.py +0 -0
  229. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/envs/package/unpack.py +0 -0
  230. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/envs/pull.py +0 -0
  231. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/__init__.py +0 -0
  232. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/_lifecycle/__init__.py +0 -0
  233. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/_lifecycle/auth.py +0 -0
  234. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/_lifecycle/bootstrap.py +0 -0
  235. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
  236. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
  237. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/_lifecycle/deadline.py +0 -0
  238. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/_lifecycle/http.py +0 -0
  239. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/_lifecycle/instance.py +0 -0
  240. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/_lifecycle/poll.py +0 -0
  241. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/_lifecycle/poll_instance.py +0 -0
  242. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/_lifecycle/provider.py +0 -0
  243. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/_lifecycle/worker.py +0 -0
  244. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/allocator.py +0 -0
  245. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/artifacts/__init__.py +0 -0
  246. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/artifacts/hf.py +0 -0
  247. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/artifacts/preload_runpod.py +0 -0
  248. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/artifacts/weight_cache.py +0 -0
  249. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/base.py +0 -0
  250. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/fit_errors.py +0 -0
  251. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/lambda_/__init__.py +0 -0
  252. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/lambda_/api.py +0 -0
  253. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/lambda_/auth.py +0 -0
  254. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/lambda_/gpus.py +0 -0
  255. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/lambda_/jobs/__init__.py +0 -0
  256. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/lambda_/jobs/builders.py +0 -0
  257. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/lambda_/jobs/reap.py +0 -0
  258. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/lambda_/preflight.py +0 -0
  259. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/lambda_/pricing.py +0 -0
  260. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/preflight.py +0 -0
  261. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/realized.py +0 -0
  262. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/runpod/__init__.py +0 -0
  263. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/runpod/api.py +0 -0
  264. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/runpod/auth.py +0 -0
  265. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/runpod/cost.py +0 -0
  266. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/runpod/gpus.py +0 -0
  267. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/runpod/job_execution.py +0 -0
  268. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/runpod/jobs.py +0 -0
  269. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/runpod/preflight.py +0 -0
  270. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/runpod/pricing.py +0 -0
  271. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/runpod/resources.py +0 -0
  272. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/runpod/serverless/__init__.py +0 -0
  273. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/runpod/serverless/endpoints.py +0 -0
  274. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/sharding.py +0 -0
  275. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/vast/__init__.py +0 -0
  276. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/vast/api.py +0 -0
  277. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/vast/auth.py +0 -0
  278. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/vast/jobs/__init__.py +0 -0
  279. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/vast/jobs/builders.py +0 -0
  280. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/vast/preflight.py +0 -0
  281. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/providers/vast/pricing.py +0 -0
  282. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/py.typed +0 -0
  283. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/__init__.py +0 -0
  284. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/artifacts.py +0 -0
  285. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/attempts.py +0 -0
  286. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/costs.py +0 -0
  287. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/deadlines.py +0 -0
  288. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/reconciliation.py +0 -0
  289. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/results/__init__.py +0 -0
  290. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/results/checkpoints.py +0 -0
  291. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/results/verified_revisions.py +0 -0
  292. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/status.py +0 -0
  293. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/submit.py +0 -0
  294. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/supervise/__init__.py +0 -0
  295. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/supervise/attach.py +0 -0
  296. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/supervise/deploy.py +0 -0
  297. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/supervise/lifecycle.py +0 -0
  298. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/supervise/recovery.py +0 -0
  299. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/supervise/retry_decision.py +0 -0
  300. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/supervise/seed_submission.py +0 -0
  301. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/supervise/transitions.py +0 -0
  302. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/runner/weight_cache.py +0 -0
  303. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/schema/__init__.py +0 -0
  304. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/schema/fields.py +0 -0
  305. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/serve/__init__.py +0 -0
  306. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/serve/adapter_check.py +0 -0
  307. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/serve/deploy.py +0 -0
  308. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/serve/errors.py +0 -0
  309. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/serve/export.py +0 -0
  310. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/serve/preflight.py +0 -0
  311. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/serve/responses.py +0 -0
  312. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/serve/streaming.py +0 -0
  313. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/serve/thinking.py +0 -0
  314. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/serve/urls.py +0 -0
  315. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/__init__.py +0 -0
  316. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/__main__.py +0 -0
  317. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/app.py +0 -0
  318. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/billing/__init__.py +0 -0
  319. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/billing/charges.py +0 -0
  320. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/billing/retry.py +0 -0
  321. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/domain/__init__.py +0 -0
  322. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/domain/checkpoints.py +0 -0
  323. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/domain/environment_registry.py +0 -0
  324. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/domain/envs.py +0 -0
  325. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/domain/projects.py +0 -0
  326. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/domain/reconcile.py +0 -0
  327. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/domain/repo_cleanup.py +0 -0
  328. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/domain/run_registry.py +0 -0
  329. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/domain/teacher_broker.py +0 -0
  330. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/domain/teacher_errors.py +0 -0
  331. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/domain/teacher_requests.py +0 -0
  332. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/platform/__init__.py +0 -0
  333. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/platform/auth.py +0 -0
  334. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/platform/db.py +0 -0
  335. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/platform/deps.py +0 -0
  336. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/platform/internal_client.py +0 -0
  337. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/platform/locks.py +0 -0
  338. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/platform/runtime.py +0 -0
  339. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/routes/__init__.py +0 -0
  340. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/routes/envs.py +0 -0
  341. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/routes/meta.py +0 -0
  342. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/routes/runs.py +0 -0
  343. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/routes/serving.py +0 -0
  344. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/routes/serving_completion.py +0 -0
  345. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/routes/serving_revisions.py +0 -0
  346. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/routes/serving_smoke.py +0 -0
  347. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/server/routes/teacher.py +0 -0
  348. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/teacher/__init__.py +0 -0
  349. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/teacher/limits.py +0 -0
  350. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/flash/teacher/retry_contract.py +0 -0
  351. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/scripts/build_dev_dist.py +0 -0
  352. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/scripts/check_file_size.py +0 -0
  353. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/scripts/check_function_size.py +0 -0
  354. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/scripts/check_verl_pin_exists.py +0 -0
  355. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/scripts/scrub_history.sh +0 -0
  356. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/__init__.py +0 -0
  357. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/_helpers/__init__.py +0 -0
  358. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/_helpers/profile.py +0 -0
  359. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/_helpers/runner.py +0 -0
  360. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/_helpers/specs.py +0 -0
  361. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/_helpers/teacher.py +0 -0
  362. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/_helpers/vast.py +0 -0
  363. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/conftest.py +0 -0
  364. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/fixtures/math_eval.jsonl +0 -0
  365. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/fixtures/math_train.jsonl +0 -0
  366. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/live/__init__.py +0 -0
  367. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/live/conftest.py +0 -0
  368. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/live/test_lambda_live.py +0 -0
  369. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/live/test_runpod_live.py +0 -0
  370. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/live/test_sft_thinking_render_live.py +0 -0
  371. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/live/test_vast_live.py +0 -0
  372. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_accounting_coverage.py +0 -0
  373. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_agent_flash_cli_contract.py +0 -0
  374. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_algorithms.py +0 -0
  375. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_allocator.py +0 -0
  376. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_backend_jobspec_contract.py +0 -0
  377. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_bake_kernel_cache.py +0 -0
  378. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_base_model_provenance.py +0 -0
  379. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_billing_retry.py +0 -0
  380. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_build_context_contract.py +0 -0
  381. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_cancel_remote.py +0 -0
  382. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_catalog_consistency.py +0 -0
  383. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_catalog_only_models.py +0 -0
  384. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_charge_pricing.py +0 -0
  385. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_checkpoints.py +0 -0
  386. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_cli_commands.py +0 -0
  387. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_cli_commands_coverage.py +0 -0
  388. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_cli_credential_shadowing.py +0 -0
  389. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_cli_errors.py +0 -0
  390. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_cli_estimate.py +0 -0
  391. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_cli_gpus_flag.py +0 -0
  392. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_cli_help.py +0 -0
  393. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_cli_main_coverage.py +0 -0
  394. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_cli_managed.py +0 -0
  395. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_cli_render_coverage.py +0 -0
  396. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_cli_render_theme.py +0 -0
  397. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_cli_traces.py +0 -0
  398. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_cli_wandb_warning.py +0 -0
  399. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_client.py +0 -0
  400. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_client_import_purity.py +0 -0
  401. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_client_server_integration.py +0 -0
  402. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_client_stream_reads.py +0 -0
  403. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_config_env_vars.py +0 -0
  404. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_config_overrides.py +0 -0
  405. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_controlled_experiment_repairs.py +0 -0
  406. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_cost_analytical.py +0 -0
  407. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_cost_equation.py +0 -0
  408. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_cost_estimate.py +0 -0
  409. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_cost_hardware.py +0 -0
  410. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_cost_models.py +0 -0
  411. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_dataset_profile.py +0 -0
  412. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_deploy_alias_move_warning.py +0 -0
  413. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_deploy_latency.py +0 -0
  414. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_dev_channel.py +0 -0
  415. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_endpoint_name.py +0 -0
  416. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_env_cache_evict.py +0 -0
  417. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_env_delete.py +0 -0
  418. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_env_download.py +0 -0
  419. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_env_download_api.py +0 -0
  420. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_env_evaluations.py +0 -0
  421. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_env_list_api.py +0 -0
  422. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_env_list_cli.py +0 -0
  423. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_env_list_hub.py +0 -0
  424. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_env_no_install.py +0 -0
  425. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_env_publish.py +0 -0
  426. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_env_pull.py +0 -0
  427. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_env_pull_coverage.py +0 -0
  428. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_env_pull_loader_coverage.py +0 -0
  429. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_env_pull_managed_control_plane.py +0 -0
  430. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_env_push.py +0 -0
  431. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_env_rate_limit_resolve.py +0 -0
  432. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_env_ref_pinning.py +0 -0
  433. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_env_test.py +0 -0
  434. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_envs_coverage.py +0 -0
  435. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_export.py +0 -0
  436. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_flash_mvp.py +0 -0
  437. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_flash_worker.py +0 -0
  438. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_flashinfer_cache_dirs.py +0 -0
  439. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_freesolo_api_transport.py +0 -0
  440. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_github_urlopen_retry.py +0 -0
  441. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_gpu_type_single_field.py +0 -0
  442. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_gpus.py +0 -0
  443. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_grpo_params.py +0 -0
  444. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_grpo_resident_sizing.py +0 -0
  445. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_grpo_reward_batching.py +0 -0
  446. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_health_liveness.py +0 -0
  447. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_hf_retry.py +0 -0
  448. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_idle_endpoint_reaper.py +0 -0
  449. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_infisical_secrets.py +0 -0
  450. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_instance_bootstrap_coverage.py +0 -0
  451. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_internal_client.py +0 -0
  452. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_jobs.py +0 -0
  453. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_kernel_cache.py +0 -0
  454. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_kernel_fingerprint.py +0 -0
  455. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_kv_util.py +0 -0
  456. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_lambda_api_coverage.py +0 -0
  457. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_lambda_runner.py +0 -0
  458. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_logging.py +0 -0
  459. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_login_perms.py +0 -0
  460. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_lora_rank_coverage.py +0 -0
  461. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_managed_config_fields.py +0 -0
  462. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_managed_hf_repo.py +0 -0
  463. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_metrics_schema_agent_contract.py +0 -0
  464. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_mig_guard.py +0 -0
  465. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_multi_gpu_gate.py +0 -0
  466. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_multimodal_training.py +0 -0
  467. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_named_reward_metrics.py +0 -0
  468. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_oom_escalate_gpu.py +0 -0
  469. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_opd.py +0 -0
  470. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_opd_limits.py +0 -0
  471. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_opd_multiturn_eos_boundary.py +0 -0
  472. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_opd_resume_safety.py +0 -0
  473. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_opd_train.py +0 -0
  474. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_orchestrator_flash.py +0 -0
  475. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_packing.py +0 -0
  476. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_packing_coverage.py +0 -0
  477. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_parasail_teacher.py +0 -0
  478. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_poll_helpers.py +0 -0
  479. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_preflight.py +0 -0
  480. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_projects.py +0 -0
  481. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_prompt_budget.py +0 -0
  482. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_provider_preflight_coverage.py +0 -0
  483. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_provider_routing.py +0 -0
  484. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_provider_teardown_robustness.py +0 -0
  485. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_providers_symmetry.py +0 -0
  486. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_realized_cost.py +0 -0
  487. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_repo_cleanup.py +0 -0
  488. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_resolve_params_b.py +0 -0
  489. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_resume_on_retry.py +0 -0
  490. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_rl_train.py +0 -0
  491. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_rollout_samples.py +0 -0
  492. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_runmgmt.py +0 -0
  493. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_runpod_api_delete.py +0 -0
  494. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_runpod_key_fingerprint.py +0 -0
  495. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_runpod_key_waterfall.py +0 -0
  496. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_serve.py +0 -0
  497. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_serve_reasoning_content.py +0 -0
  498. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_server_api.py +0 -0
  499. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_server_app_coverage.py +0 -0
  500. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_server_auth_singleflight.py +0 -0
  501. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_server_billing.py +0 -0
  502. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_server_checkpoints_coverage.py +0 -0
  503. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_server_db.py +0 -0
  504. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_server_envs_coverage.py +0 -0
  505. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_server_locks_coverage.py +0 -0
  506. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_server_standalone.py +0 -0
  507. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_serving_context_preflight.py +0 -0
  508. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_serving_contract.py +0 -0
  509. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_serving_schema_coverage.py +0 -0
  510. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_sft_chunked_nll.py +0 -0
  511. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_sft_example_selection.py +0 -0
  512. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_sft_gc_off.py +0 -0
  513. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_sft_max_context.py +0 -0
  514. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_sft_startup_block.py +0 -0
  515. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_sft_workload.py +0 -0
  516. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_spec_and_validation.py +0 -0
  517. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_step_floor.py +0 -0
  518. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_step_metrics.py +0 -0
  519. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_step_timing.py +0 -0
  520. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_structured_outputs.py +0 -0
  521. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_teacher_broker.py +0 -0
  522. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_teacher_encoding_contract.py +0 -0
  523. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_thinking_config.py +0 -0
  524. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_train_context_preflight.py +0 -0
  525. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_training_controls.py +0 -0
  526. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_type_comment_prose.py +0 -0
  527. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_vast_api.py +0 -0
  528. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_vast_api_coverage.py +0 -0
  529. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_vast_offers.py +0 -0
  530. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_vast_provider_coverage.py +0 -0
  531. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_vast_runner.py +0 -0
  532. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_verified_revisions.py +0 -0
  533. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_verifiers.py +0 -0
  534. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_version.py +0 -0
  535. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_vram_architecture.py +0 -0
  536. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_wandb_link.py +0 -0
  537. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_wandb_naming.py +0 -0
  538. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_warmstart_error_attribution.py +0 -0
  539. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_weight_cache.py +0 -0
  540. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_worker_dryrun.py +0 -0
  541. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_worker_hardexit.py +0 -0
  542. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_worker_image.py +0 -0
  543. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_worker_init_heartbeat.py +0 -0
  544. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_worker_thinking.py +0 -0
  545. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_workflow_contracts.py +0 -0
  546. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_workload_profile.py +0 -0
  547. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.43}/tests/test_zero2_sharding_gate.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: freesolo-flash-dev
3
- Version: 1.2.37
3
+ Version: 1.2.43
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
@@ -0,0 +1,375 @@
1
+ """Fused-expert LoRA targeting, validation, and export normalization."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+ from collections import Counter
7
+ from collections.abc import Mapping
8
+ from typing import Any
9
+
10
+ from flash.adapters.lora_rank import (
11
+ _rank_for_module,
12
+ declared_lora_ranks,
13
+ lora_tensor_rank_disagrees,
14
+ )
15
+ from flash.core.catalog import get_model
16
+
17
+ _QWEN36_MODEL_ID = "Qwen/Qwen3.6-35B-A3B"
18
+ _QWEN36_EXPERT_TARGET_PARAMETERS = (
19
+ "mlp.experts.gate_up_proj",
20
+ "mlp.experts.down_proj",
21
+ )
22
+ _QWEN36_FUSED_TARGET_DIMENSIONS = {
23
+ "mlp.experts.gate_up_proj": (2048, 1024),
24
+ "mlp.experts.down_proj": (512, 2048),
25
+ }
26
+ _QWEN36_FUSED_TARGET_RUNGS = {
27
+ "mlp.experts.down_proj": "",
28
+ "mlp.experts.gate_up_proj": "base_layer",
29
+ }
30
+ _FUSED_EXPERT_SYNTHETIC_MODULES = frozenset({"experts", "base_layer"})
31
+ _FUSED_EXPERT_WRAPPER_MODULES = ("mlp.experts", "mlp.experts.base_layer")
32
+ _INVALID_FUSED_LOCATION = object()
33
+
34
+ _LoraTensor = tuple[str, str, str, str, tuple[int, ...]]
35
+ _LoraPair = tuple[tuple[int, ...], tuple[int, ...]]
36
+
37
+
38
+ def lora_target_parameters(model_id: str | None) -> list[str] | None:
39
+ """Return direct parameter targets required by the model's fused expert layout."""
40
+ if model_id == _QWEN36_MODEL_ID:
41
+ return list(_QWEN36_EXPERT_TARGET_PARAMETERS)
42
+ return None
43
+
44
+
45
+ def validate_fused_expert_adapter_config(config: Mapping[str, Any], model_id: str) -> None:
46
+ """Validate the exact current adapter config required by a fused-expert model."""
47
+ required = lora_target_parameters(model_id)
48
+ if not required:
49
+ return
50
+
51
+ targets = config.get("target_parameters")
52
+ if not isinstance(targets, list):
53
+ raise ValueError(
54
+ f"adapter for {model_id} omits required expert targets; "
55
+ "target_parameters must be a list of strings"
56
+ )
57
+ if any(not isinstance(target, str) for target in targets):
58
+ raise ValueError(
59
+ f"adapter for {model_id} must declare target_parameters as a list of strings"
60
+ )
61
+ if len(targets) != len(set(targets)):
62
+ raise ValueError(f"adapter for {model_id} must declare unique target_parameters")
63
+ if set(targets) != set(required):
64
+ raise ValueError(
65
+ f"adapter for {model_id} must declare exactly the fused expert targets {required}"
66
+ )
67
+
68
+ rank_pattern = config.get("rank_pattern")
69
+ _validate_rank_pattern(rank_pattern, model_id)
70
+ declared = declared_lora_ranks(config)
71
+ unresolved = [target for target in required if _rank_for_module(target, declared) is None]
72
+ if unresolved:
73
+ raise ValueError(
74
+ f"adapter for {model_id} has no resolved LoRA rank for fused targets {unresolved}"
75
+ )
76
+
77
+ modules = config.get("target_modules")
78
+ if isinstance(modules, str):
79
+ if modules != "all-linear":
80
+ raise ValueError(f"adapter for {model_id} string target_modules must be 'all-linear'")
81
+ # all-linear names no modules, so only a default rank can resolve every ordinary target.
82
+ if declared.default is None:
83
+ raise ValueError(
84
+ f"adapter for {model_id} has no resolved default LoRA rank for 'all-linear' "
85
+ "target_modules"
86
+ )
87
+ return
88
+ if (
89
+ not isinstance(modules, list)
90
+ or not modules
91
+ or any(not isinstance(module, str) or not module for module in modules)
92
+ ):
93
+ raise ValueError(
94
+ f"adapter for {model_id} target_modules must be 'all-linear' or a non-empty "
95
+ "list of non-empty strings"
96
+ )
97
+ synthetic = [module for module in modules if _targets_fused_expert_wrapper(module)]
98
+ if synthetic:
99
+ raise ValueError(
100
+ f"adapter for {model_id} contains invalid synthetic target_modules {sorted(synthetic)}"
101
+ )
102
+ unresolved = [module for module in modules if _rank_for_module(module, declared) is None]
103
+ if unresolved:
104
+ raise ValueError(
105
+ f"adapter for {model_id} has no resolved LoRA rank for ordinary target_modules "
106
+ f"{unresolved}"
107
+ )
108
+
109
+
110
+ def _validate_rank_pattern(rank_pattern: Any, model_id: str) -> None:
111
+ """Validate positive ranks and PEFT's anchored regex pattern syntax."""
112
+ message = (
113
+ f"adapter for {model_id} rank_pattern must map valid non-empty string patterns "
114
+ "to positive integer ranks"
115
+ )
116
+ if rank_pattern is None:
117
+ return
118
+ if not isinstance(rank_pattern, Mapping):
119
+ raise ValueError(message)
120
+ for pattern, rank in rank_pattern.items():
121
+ if (
122
+ not isinstance(pattern, str)
123
+ or not pattern.strip()
124
+ or not isinstance(rank, int)
125
+ or isinstance(rank, bool)
126
+ or rank <= 0
127
+ ):
128
+ raise ValueError(message)
129
+ try:
130
+ re.compile(rf"(.*\.)?({pattern})$")
131
+ except re.error as exc:
132
+ raise ValueError(message) from exc
133
+
134
+
135
+ def _targets_fused_expert_wrapper(module: str) -> bool:
136
+ """Return whether PEFT suffix matching binds this target to an expert wrapper."""
137
+ return any(
138
+ module == wrapper or module.endswith(f".{wrapper}") or wrapper.endswith(f".{module}")
139
+ for wrapper in _FUSED_EXPERT_WRAPPER_MODULES
140
+ )
141
+
142
+
143
+ def normalize_verl_fused_expert_export(config: dict[str, Any], model_id: str) -> None:
144
+ """Write the canonical fused targets into a verl-exported adapter config."""
145
+ targets = lora_target_parameters(model_id)
146
+ if not targets:
147
+ return
148
+ config["target_parameters"] = targets
149
+ modules = config.get("target_modules")
150
+ if modules is None:
151
+ raise ValueError(
152
+ f"exported adapter for {model_id} must retain ordinary LoRA target_modules"
153
+ )
154
+ if isinstance(modules, list):
155
+ config["target_modules"] = [
156
+ module
157
+ for module in modules
158
+ if not isinstance(module, str) or module not in _FUSED_EXPERT_SYNTHETIC_MODULES
159
+ ]
160
+
161
+
162
+ def has_complete_fused_expert_tensors(
163
+ tensors: Mapping[str, tuple[int, ...]], config: Mapping[str, Any], model_id: str
164
+ ) -> bool:
165
+ """Return whether fused and ordinary LoRA tensors match the declared PEFT topology."""
166
+ expected = _expected_fused_expert_rungs(config, model_id)
167
+ if expected is None:
168
+ return False
169
+ parsed = [
170
+ tensor
171
+ for key, shape in tensors.items()
172
+ if (tensor := _parse_lora_tensor(key, shape)) is not None
173
+ ]
174
+ if len({adapter_name for _, _, adapter_name, _, _ in parsed}) != 1:
175
+ return False
176
+ return _has_complete_fused_rungs(parsed, expected, model_id) and _has_ordinary_evidence(
177
+ parsed, config, expected
178
+ )
179
+
180
+
181
+ def _parse_lora_tensor(key: str, shape: tuple[int, ...]) -> _LoraTensor | None:
182
+ """Parse one canonical PEFT LoRA tensor key."""
183
+ matches = [
184
+ (factor, infix) for factor, infix in (("A", ".lora_A."), ("B", ".lora_B.")) if infix in key
185
+ ]
186
+ if len(matches) != 1:
187
+ return None
188
+ factor, infix = matches[0]
189
+ module_path, _, leaf = key.partition(infix)
190
+ leaf_parts = leaf.split(".")
191
+ if not module_path or len(leaf_parts) != 2:
192
+ return None
193
+ adapter_name, parameter = leaf_parts
194
+ if not adapter_name or parameter != "weight":
195
+ return None
196
+ return module_path, factor, adapter_name, key, shape
197
+
198
+
199
+ def _expected_fused_expert_rungs(
200
+ config: Mapping[str, Any], model_id: str
201
+ ) -> dict[str, dict[str, _LoraPair]] | None:
202
+ """Return the exact target-specific PEFT rung geometry for each fused owner."""
203
+ targets = lora_target_parameters(model_id)
204
+ if model_id != _QWEN36_MODEL_ID or not targets:
205
+ return None
206
+ model = get_model(model_id)
207
+ experts = model.lora_expert_count
208
+ if experts <= 0 or model.num_layers <= 0:
209
+ return None
210
+ fused_count = model.num_layers * experts
211
+ catalog_dimensions = Counter(
212
+ (input_dim, output_dim)
213
+ for input_dim, output_dim, count in model.lora_target_shapes
214
+ if count == fused_count
215
+ )
216
+ if catalog_dimensions != Counter(_QWEN36_FUSED_TARGET_DIMENSIONS.values()):
217
+ return None
218
+
219
+ declared = declared_lora_ranks(config)
220
+ expected: dict[str, dict[str, _LoraPair]] = {}
221
+ for target in targets:
222
+ rank = _rank_for_module(target, declared)
223
+ dimensions = _QWEN36_FUSED_TARGET_DIMENSIONS.get(target)
224
+ rung = _QWEN36_FUSED_TARGET_RUNGS.get(target)
225
+ owner, separator, _ = target.rpartition(".")
226
+ if rank is None or dimensions is None or rung is None or not separator or not owner:
227
+ return None
228
+ input_dim, output_dim = dimensions
229
+ stacked_rank = rank * experts
230
+ expected.setdefault(owner, {})[rung] = (
231
+ (stacked_rank, input_dim),
232
+ (output_dim, stacked_rank),
233
+ )
234
+ return expected
235
+
236
+
237
+ def _has_complete_fused_rungs(
238
+ tensors: list[_LoraTensor], expected: Mapping[str, Mapping[str, _LoraPair]], model_id: str
239
+ ) -> bool:
240
+ """Validate every concrete fused owner, rung, namespace, and factor shape."""
241
+ model = get_model(model_id)
242
+ for owner, expected_rungs in expected.items():
243
+ factors: dict[str, dict[str, dict[str, dict[str, tuple[int, ...]]]]] = {}
244
+ for module_path, factor, adapter_name, _key, shape in tensors:
245
+ location = _fused_tensor_location(module_path, owner, frozenset(expected_rungs))
246
+ if location is _INVALID_FUSED_LOCATION:
247
+ return False
248
+ if location is None:
249
+ continue
250
+ instance, rung = location
251
+ factors.setdefault(instance, {}).setdefault(rung, {}).setdefault(adapter_name, {})[
252
+ factor
253
+ ] = shape
254
+ if not factors:
255
+ return False
256
+ for seen_rungs in factors.values():
257
+ if set(seen_rungs) != set(expected_rungs):
258
+ return False
259
+ for rung, expected_pair in expected_rungs.items():
260
+ namespaces = seen_rungs[rung]
261
+ if len(namespaces) != 1:
262
+ return False
263
+ seen_factors = next(iter(namespaces.values()))
264
+ if _lora_pair_shapes(seen_factors) != expected_pair:
265
+ return False
266
+ expert_layers = {
267
+ prefix
268
+ for instance in factors
269
+ for prefix in [_layer_prefix(instance)]
270
+ if prefix is not None
271
+ }
272
+ layer_roots = {prefix.rsplit(".", 1)[0] for prefix in expert_layers}
273
+ if len(layer_roots) != 1:
274
+ return False
275
+ layer_root = next(iter(layer_roots))
276
+ expected_layers = {f"{layer_root}.{index}" for index in range(model.num_layers)}
277
+ if expert_layers != expected_layers:
278
+ return False
279
+ return True
280
+
281
+
282
+ def _fused_tensor_location(
283
+ module_path: str, owner: str, rungs: frozenset[str]
284
+ ) -> tuple[str, str] | object | None:
285
+ """Locate one tensor on an exact concrete fused owner rung."""
286
+ if module_path.endswith(f".{owner}"):
287
+ instance, rung = module_path[: -len(owner) - 1], ""
288
+ else:
289
+ marker = f".{owner}."
290
+ if marker not in module_path:
291
+ return None
292
+ instance, rung = module_path.rsplit(marker, 1)
293
+ if rung not in rungs:
294
+ return _INVALID_FUSED_LOCATION
295
+ layer_prefix = _layer_prefix(instance)
296
+ if layer_prefix is None or instance != layer_prefix:
297
+ return _INVALID_FUSED_LOCATION
298
+ return f"{instance}.{owner}", rung
299
+
300
+
301
+ def _has_ordinary_evidence(
302
+ tensors: list[_LoraTensor],
303
+ config: Mapping[str, Any],
304
+ fused_rungs: Mapping[str, Mapping[str, _LoraPair]],
305
+ ) -> bool:
306
+ """Validate concrete ordinary target evidence with per-module ranks and namespaces."""
307
+ modules = config.get("target_modules")
308
+ all_linear = modules == "all-linear"
309
+ targets = () if all_linear else tuple(modules) if isinstance(modules, list) else ()
310
+ groups: dict[str, dict[str, dict[str, tuple[str, tuple[int, ...]]]]] = {}
311
+ evidence: set[str] = set()
312
+ for module_path, factor, adapter_name, key, shape in tensors:
313
+ if _is_fused_rung(module_path, fused_rungs):
314
+ continue
315
+ matched = tuple(target for target in targets if _anchored_suffix_match(module_path, target))
316
+ if not all_linear and not matched:
317
+ continue
318
+ evidence.update(matched)
319
+ groups.setdefault(module_path, {}).setdefault(adapter_name, {})[factor] = (key, shape)
320
+ if not groups or (not all_linear and evidence != set(targets)):
321
+ return False
322
+
323
+ declared = declared_lora_ranks(config)
324
+ for module_path, namespaces in groups.items():
325
+ if len(namespaces) != 1 or _rank_for_module(module_path, declared) is None:
326
+ return False
327
+ factors = next(iter(namespaces.values()))
328
+ if set(factors) != {"A", "B"}:
329
+ return False
330
+ for key, shape in factors.values():
331
+ if not _is_positive_2d(shape) or lora_tensor_rank_disagrees(key, shape, declared):
332
+ return False
333
+ return True
334
+
335
+
336
+ def _is_fused_rung(module_path: str, fused_rungs: Mapping[str, Mapping[str, _LoraPair]]) -> bool:
337
+ """Return whether a module path is one of the exact fused wrapper rungs."""
338
+ return any(
339
+ _fused_tensor_location(module_path, owner, frozenset(rungs))
340
+ not in (None, _INVALID_FUSED_LOCATION)
341
+ for owner, rungs in fused_rungs.items()
342
+ )
343
+
344
+
345
+ def _anchored_suffix_match(module_path: str, target: str) -> bool:
346
+ """Mirror PEFT list-target matching without accepting partial segment suffixes."""
347
+ return module_path == target or module_path.endswith(f".{target}")
348
+
349
+
350
+ def _is_positive_2d(shape: tuple[int, ...]) -> bool:
351
+ """Return whether a tensor shape is positive, integral, and two-dimensional."""
352
+ return len(shape) == 2 and all(
353
+ isinstance(dimension, int) and not isinstance(dimension, bool) and dimension > 0
354
+ for dimension in shape
355
+ )
356
+
357
+
358
+ def _lora_pair_shapes(factors: Mapping[str, tuple[int, ...]]) -> _LoraPair | None:
359
+ """Return one complete positive 2-D A/B shape pair."""
360
+ if set(factors) != {"A", "B"}:
361
+ return None
362
+ shape_a = factors["A"]
363
+ shape_b = factors["B"]
364
+ if not _is_positive_2d(shape_a) or not _is_positive_2d(shape_b):
365
+ return None
366
+ return shape_a, shape_b
367
+
368
+
369
+ def _layer_prefix(path: str) -> str | None:
370
+ """Return the concrete ``...layers.N`` prefix in a tensor path, if present."""
371
+ segments = path.split(".")
372
+ for index in range(len(segments) - 2, -1, -1):
373
+ if segments[index] == "layers" and segments[index + 1].isdigit():
374
+ return ".".join(segments[: index + 2])
375
+ return None
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from dataclasses import asdict, dataclass, replace
6
+ from math import ceil
6
7
  from typing import Any
7
8
 
8
9
  ALGORITHMS = ("sft", "grpo", "opd")
@@ -622,6 +623,10 @@ def resolve_vocab_size(model_id: str, revision: str = "") -> int:
622
623
  return vocab_size_for(model_id)
623
624
 
624
625
 
626
+ def _with_merge_disk_floor(info: ModelInfo) -> ModelInfo:
627
+ return replace(info, min_disk_gb=max(info.min_disk_gb, ceil(info.params_b * 2) + 64))
628
+
629
+
625
630
  def resolve_model(model_id: str, algorithm: str, model_revision: str = "") -> ModelInfo:
626
631
  """Resolve a curated model, validated for ``algorithm``; anything uncataloged is rejected.
627
632
 
@@ -643,9 +648,8 @@ def resolve_model(model_id: str, algorithm: str, model_revision: str = "") -> Mo
643
648
  params_b=params_b,
644
649
  params=f"{params_b:.1f}B",
645
650
  vocab_size=vocab_size,
646
- min_disk_gb=max(info.min_disk_gb, int(params_b * 2) + 64),
647
651
  )
648
- return info
652
+ return _with_merge_disk_floor(info)
649
653
 
650
654
 
651
655
  def validate_model_for_algorithm(model_id: str, algorithm: str) -> ModelInfo:
@@ -660,4 +664,4 @@ def validate_model_for_algorithm(model_id: str, algorithm: str) -> ModelInfo:
660
664
 
661
665
 
662
666
  def public_model_rows() -> list[dict[str, Any]]:
663
- return [m.to_dict() for m in list_models()]
667
+ return [_with_merge_disk_floor(model).to_dict() for model in list_models()]
@@ -17,6 +17,7 @@ import time
17
17
  import traceback
18
18
 
19
19
  from flash._internal.diagnostics import sanitize_diagnostic
20
+ from flash.adapters.fused_experts import lora_target_parameters
20
21
  from flash.core.spec import FIXED_SEED, load_job_spec_from_env
21
22
  from flash.engine.result.accounting import RunMetrics
22
23
  from flash.engine.worker.backend_common import collect_ray_failure_logs
@@ -56,9 +57,8 @@ from flash.engine.worker.io.wandb_log import (
56
57
  )
57
58
  from flash.engine.worker.model.adapter import (
58
59
  _download_adapter,
59
- lora_target_parameters,
60
60
  make_lora,
61
- validate_lora_target_parameters,
61
+ validate_warmstart_adapter,
62
62
  )
63
63
  from flash.engine.worker.model.decoding import (
64
64
  graded_text,
@@ -503,7 +503,7 @@ __all__ = [
503
503
  "think_token_count",
504
504
  "thinking_text",
505
505
  "upload_resume_checkpoint",
506
- "validate_lora_target_parameters",
506
+ "validate_warmstart_adapter",
507
507
  "wait_for_gpu",
508
508
  "wandb_run_name",
509
509
  "write_base_model_provenance",
@@ -471,29 +471,14 @@ def ray_num_cpus(gpu_count: int = 1, *, cap: int = 16) -> int:
471
471
  return max(floor, min(affinity, cap))
472
472
 
473
473
 
474
- def run_verl_training(
474
+ def _run_streaming_verl_subprocess(
475
475
  cmd: list[str],
476
476
  *,
477
477
  env: dict[str, str],
478
- on_step: Callable[[int], None] | None = None,
479
- on_line: Callable[[str], None] | None = None,
480
- heartbeat: Callable[[], None] | None = None,
481
- step_pattern: str = r"step:\s*(\d+)",
482
- heartbeat_interval_s: float = 20.0,
483
- tail: ChildOutputTail | None = None,
478
+ on_line: Callable[[str], None],
479
+ errors: str | None = None,
484
480
  ) -> int:
485
- """run a verl trainer subprocess, streaming stdout and surfacing step progress.
486
-
487
- returns the process exit code. stdout+stderr are merged and scanned line by line: ``on_line``
488
- receives every line, ``on_step`` receives each parsed training step, and ``heartbeat`` is called
489
- at most once per ``heartbeat_interval_s``. callback failures terminate the child before they are
490
- re-raised so a failed required checkpoint upload cannot leave paid training running unattended.
491
- """
492
- step_re = re.compile(step_pattern)
493
- child_tail = tail if tail is not None else ChildOutputTail()
494
- # before the child exists, so any grandchild it orphans reparents here and can actually be
495
- # reaped. this process is not pid 1 -- the runpod handler is -- so without it every wait below
496
- # answers ChildProcessError for a zombie nobody will collect.
481
+ """stream a verl subprocess under the shared process-group lifecycle supervisor."""
497
482
  adopt_orphaned_descendants()
498
483
  proc = subprocess.Popen(
499
484
  cmd,
@@ -501,87 +486,88 @@ def run_verl_training(
501
486
  stdout=subprocess.PIPE,
502
487
  stderr=subprocess.STDOUT,
503
488
  text=True,
489
+ errors=errors,
504
490
  bufsize=1,
505
491
  start_new_session=True,
506
492
  )
507
- # start_new_session makes the leader pid the stable group id even after that leader is reaped.
493
+ # start_new_session keeps the group addressable after the leader is reaped.
508
494
  process_group_id = proc.pid
509
- last_hb = 0.0
510
495
  try:
511
- # the child's exit is watched independently of pipe EOF. a grandchild holding the inherited
512
- # pipe open after the trainer dies would otherwise keep the loop below running forever, on a
513
- # paid gpu, having already lost the process whose output it is waiting for.
514
496
  with _ChildExitWatchdog(
515
497
  proc, process_group_id=process_group_id, grace_s=_ORPHANED_PIPE_GRACE_S
516
498
  ) as watchdog:
517
499
  assert proc.stdout is not None
518
500
  for line in proc.stdout:
519
- # held across the callbacks, not just the arrival: on_step uploads a checkpoint, and
520
- # a reader inside one is working, not stuck.
521
501
  with watchdog.handling_line():
522
- print(line, end="", flush=True)
523
- child_tail.record(line)
524
- if on_line is not None:
525
- on_line(line)
526
- m = step_re.search(line)
527
- if m and on_step is not None:
528
- on_step(int(m.group(1)))
529
- if heartbeat is not None:
530
- now = time.monotonic()
531
- if now - last_hb >= heartbeat_interval_s:
532
- heartbeat()
533
- last_hb = now
502
+ on_line(line)
534
503
  except BaseException:
535
504
  kill_process_group(proc, process_group_id=process_group_id)
536
505
  raise
537
506
  finally:
538
507
  if proc.poll() is None:
539
- # BOUNDED. EOF is not the child's exit, so a child that outlives its own stdout would
540
- # park the attempt here. one that has not exited within the grace after its stdout closed
541
- # is not going to, so tear the group down and let the wait inside that call collect it.
542
508
  try:
543
509
  proc.wait(timeout=_TEARDOWN_GRACE_S)
544
510
  except subprocess.TimeoutExpired:
545
511
  kill_process_group(proc, process_group_id=process_group_id)
546
- # every job boundary, not just the failing ones. a straggler an earlier teardown SIGKILLed
547
- # but could not drain in time exits shortly after, and `kill_process_group` -- the only
548
- # other caller of this -- runs on exceptions alone: a worker whose later jobs all succeed
549
- # would hold that zombie for its whole life, as pid 1 with nothing else to reap it.
550
512
  reap_stragglers()
551
- collected = proc.returncode
552
- if collected is None:
553
- # the bounded wait above can end with nothing collected, which the unbounded one it replaced
554
- # could not: a group member wedged in uninterruptible io outlives even the SIGKILL inside
555
- # teardown. `int(None)` would replace that diagnosis with a TypeError, so name the survivor
556
- # instead -- callers already handle a RuntimeError from here.
513
+ if proc.returncode is None:
557
514
  raise RuntimeError(
558
515
  f"verl subprocess {proc.pid} did not exit after teardown; its process group is still "
559
516
  "holding the gpu"
560
517
  )
561
- return_code = int(collected)
518
+ return_code = int(proc.returncode)
562
519
  if watchdog.tore_down and return_code == 0:
563
- # the child exited 0 but a descendant held the pipe open past the grace, so the group was
564
- # killed to release it. reporting success here would upload whatever partial artifacts exist
565
- # as a completed run: the trainer's own exit status says nothing about the descendant that
566
- # was still running, and that descendant is why the pipe never closed.
567
520
  raise RuntimeError(
568
521
  f"verl subprocess {proc.pid} exited 0 but a descendant held its output pipe open for "
569
522
  f"{_ORPHANED_PIPE_GRACE_S:.0f}s; the process group was torn down to release the gpu"
570
523
  )
571
- try:
572
- raise_for_classified_verl_exit(return_code, child_tail)
573
- except BaseException:
574
- kill_process_group(proc, process_group_id=process_group_id)
575
- raise
576
524
  if return_code != 0:
577
- # a nonzero exit that carried no recognized signature RETURNS from the classifier rather
578
- # than raising, so this is the one failing path that reached neither teardown above. the
579
- # direct child is gone but its group need not be: a surviving EngineCore keeps its cuda
580
- # context, and a reusable worker then hands the next attempt an occupied gpu.
581
525
  kill_process_group(proc, process_group_id=process_group_id)
582
526
  return return_code
583
527
 
584
528
 
529
+ def run_verl_training(
530
+ cmd: list[str],
531
+ *,
532
+ env: dict[str, str],
533
+ on_step: Callable[[int], None] | None = None,
534
+ on_line: Callable[[str], None] | None = None,
535
+ heartbeat: Callable[[], None] | None = None,
536
+ step_pattern: str = r"step:\s*(\d+)",
537
+ heartbeat_interval_s: float = 20.0,
538
+ tail: ChildOutputTail | None = None,
539
+ ) -> int:
540
+ """run a verl trainer subprocess, streaming stdout and surfacing step progress.
541
+
542
+ returns the process exit code. stdout+stderr are merged and scanned line by line: ``on_line``
543
+ receives every line, ``on_step`` receives each parsed training step, and ``heartbeat`` is called
544
+ at most once per ``heartbeat_interval_s``. callback failures terminate the process group before
545
+ they are re-raised.
546
+ """
547
+ step_re = re.compile(step_pattern)
548
+ child_tail = tail if tail is not None else ChildOutputTail()
549
+ last_hb = 0.0
550
+
551
+ def handle_line(line: str) -> None:
552
+ nonlocal last_hb
553
+ print(line, end="", flush=True)
554
+ child_tail.record(line)
555
+ if on_line is not None:
556
+ on_line(line)
557
+ match = step_re.search(line)
558
+ if match and on_step is not None:
559
+ on_step(int(match.group(1)))
560
+ if heartbeat is not None:
561
+ now = time.monotonic()
562
+ if now - last_hb >= heartbeat_interval_s:
563
+ heartbeat()
564
+ last_hb = now
565
+
566
+ return_code = _run_streaming_verl_subprocess(cmd, env=env, on_line=handle_line)
567
+ raise_for_classified_verl_exit(return_code, child_tail)
568
+ return return_code
569
+
570
+
585
571
  _TEARDOWN_GRACE_S = 10.0
586
572
 
587
573
  # grace for a descendant holding stdout open after the trainer exits. observe child exit separately
@@ -5,7 +5,14 @@ from __future__ import annotations
5
5
  import json
6
6
  import os
7
7
  import shutil
8
+ from collections.abc import Mapping
9
+ from typing import Any
8
10
 
11
+ from flash.adapters.fused_experts import (
12
+ has_complete_fused_expert_tensors,
13
+ lora_target_parameters,
14
+ validate_fused_expert_adapter_config,
15
+ )
9
16
  from flash.adapters.lora_rank import resolve_adapter_ref
10
17
  from flash.engine.plan.recipe import RECIPE
11
18
  from flash.engine.worker.io.hf import (
@@ -17,35 +24,23 @@ from flash.engine.worker.io.hf import (
17
24
  )
18
25
  from flash.engine.worker.model.lora import (
19
26
  _read_adapter_tensor_keys,
27
+ _read_adapter_tensor_metadata,
20
28
  )
21
29
  from flash.engine.worker.runtime.pkg_proxy import W as _w
22
30
 
23
31
  _ADAPTER_DOWNLOAD_RETRIES = 4
24
32
  _ADAPTER_DOWNLOAD_BACKOFF_S = 5.0
25
- _QWEN35_EXPERT_TARGET_PARAMETERS = (
26
- "mlp.experts.gate_up_proj",
27
- "mlp.experts.down_proj",
28
- )
29
-
30
-
31
- def lora_target_parameters(model_id: str | None) -> list[str] | None:
32
- """return direct parameter targets required by the model's fused expert layout."""
33
- if model_id == "Qwen/Qwen3.6-35B-A3B":
34
- return list(_QWEN35_EXPERT_TARGET_PARAMETERS)
35
- return None
36
33
 
37
34
 
38
- def validate_lora_target_parameters(config: dict, model_id: str) -> None:
39
- """fail closed when a warm-start adapter omits required fused expert parameters."""
40
- required = set(lora_target_parameters(model_id) or ())
41
- if not required:
35
+ def validate_warmstart_adapter(config: Mapping[str, Any], model_id: str, adapter_dir: str) -> None:
36
+ """Validate a downloaded warm-start adapter without changing its config or files."""
37
+ validate_fused_expert_adapter_config(config, model_id)
38
+ if not lora_target_parameters(model_id):
42
39
  return
43
- actual = set(config.get("target_parameters") or ())
44
- missing = sorted(required - actual)
45
- if missing:
40
+ tensors = _read_adapter_tensor_metadata(adapter_dir) or {}
41
+ if not has_complete_fused_expert_tensors(tensors, config, model_id):
46
42
  raise ValueError(
47
- f"warm-start adapter for {model_id} omits required expert targets {missing}; "
48
- "retrain the source adapter with the current Flash version"
43
+ f"warm-start adapter for {model_id} does not contain complete fused expert LoRA weights"
49
44
  )
50
45
 
51
46