freesolo-flash-dev 1.2.39__tar.gz → 1.2.48__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 (569) hide show
  1. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/CHANGELOG.md +11 -0
  2. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/PKG-INFO +1 -1
  3. freesolo_flash_dev-1.2.48/flash/adapters/fused_experts.py +375 -0
  4. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/client/specs.py +3 -4
  5. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/core/spec.py +92 -189
  6. freesolo_flash_dev-1.2.48/flash/core/spec_persistence.py +227 -0
  7. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/__init__.py +3 -3
  8. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/backend_common.py +34 -30
  9. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/io/heartbeat.py +155 -118
  10. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/model/adapter.py +15 -20
  11. freesolo_flash_dev-1.2.48/flash/engine/worker/model/lora.py +157 -0
  12. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/opd_train.py +6 -7
  13. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/opd_train_runner.py +40 -28
  14. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/rl_train.py +40 -41
  15. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/rl_train_runner.py +75 -136
  16. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/sft_train.py +22 -33
  17. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/sft_train_runner.py +37 -47
  18. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/teacher/client.py +31 -4
  19. freesolo_flash_dev-1.2.48/flash/engine/worker/train/core/checkpoint_lifecycle.py +143 -0
  20. freesolo_flash_dev-1.2.48/flash/engine/worker/train/core/child/runtime.py +416 -0
  21. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/opd/batching.py +12 -4
  22. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/opd/bridge.py +25 -9
  23. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/opd/child/bridge.py +51 -4
  24. freesolo_flash_dev-1.2.48/flash/engine/worker/train/opd/child/entry.py +22 -0
  25. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/opd/child/multiturn.py +29 -12
  26. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/opd/child/plugin.py +43 -9
  27. freesolo_flash_dev-1.2.48/flash/engine/worker/train/opd/child/replay_guard.py +163 -0
  28. freesolo_flash_dev-1.2.48/flash/engine/worker/train/opd/child/runtime.py +27 -0
  29. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/opd/failures.py +17 -2
  30. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/opd/overrides.py +27 -27
  31. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/opd/scoring.py +23 -10
  32. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/opd/state.py +1 -0
  33. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/rl/checkpoints.py +34 -31
  34. freesolo_flash_dev-1.2.48/flash/engine/worker/train/rl/child/entry.py +24 -0
  35. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/rl/child/multiturn.py +30 -14
  36. freesolo_flash_dev-1.2.48/flash/engine/worker/train/rl/child/patches.py +459 -0
  37. freesolo_flash_dev-1.2.48/flash/engine/worker/train/rl/child/plugin.py +173 -0
  38. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/rl/inputs.py +6 -6
  39. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/rl/multi_turn.py +22 -21
  40. freesolo_flash_dev-1.2.48/flash/engine/worker/train/rl/reward_module.py +41 -0
  41. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/sft/checkpoints.py +35 -14
  42. freesolo_flash_dev-1.2.48/flash/engine/worker/train/sft/child/entry.py +24 -0
  43. freesolo_flash_dev-1.2.48/flash/engine/worker/train/sft/child/plugin.py +169 -0
  44. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/sft/config.py +0 -164
  45. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/verl/checkpoints.py +30 -5
  46. freesolo_flash_dev-1.2.48/flash/engine/worker/verl/child_io.py +371 -0
  47. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/verl/diagnostics.py +170 -6
  48. freesolo_flash_dev-1.2.48/flash/engine/worker/verl/parent_work.py +40 -0
  49. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/_lifecycle/bootstrap.py +19 -18
  50. freesolo_flash_dev-1.2.48/flash/providers/_lifecycle/bootstrap_console.py +108 -0
  51. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/_lifecycle/instance.py +16 -40
  52. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/artifacts/hf.py +10 -0
  53. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/runpod/resources.py +2 -2
  54. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/runpod/serverless/endpoints.py +65 -20
  55. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/vast/jobs/builders.py +4 -0
  56. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/preparation.py +2 -0
  57. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/pyproject.toml +2 -2
  58. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_adapter_shard_completeness.py +95 -4
  59. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_backend_common.py +13 -914
  60. freesolo_flash_dev-1.2.48/tests/test_checkpoint_lifecycle.py +132 -0
  61. freesolo_flash_dev-1.2.48/tests/test_console_upload.py +89 -0
  62. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_flash_worker.py +69 -22
  63. freesolo_flash_dev-1.2.48/tests/test_fused_expert_warmstart.py +651 -0
  64. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_grpo_params.py +8 -8
  65. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_grpo_reward_batching.py +4 -1
  66. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_instance_bootstrap_coverage.py +5 -3
  67. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_jobs.py +26 -0
  68. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_lambda_runner.py +26 -9
  69. freesolo_flash_dev-1.2.48/tests/test_lora_rank_preflight.py +623 -0
  70. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_multimodal_training.py +2 -2
  71. freesolo_flash_dev-1.2.48/tests/test_opd_multiturn_failure_exit.py +161 -0
  72. freesolo_flash_dev-1.2.48/tests/test_opd_replay_guard.py +219 -0
  73. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_opd_train.py +325 -34
  74. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_rl_train.py +622 -765
  75. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_sft_train.py +260 -83
  76. freesolo_flash_dev-1.2.48/tests/test_spec_contract_bytes.py +307 -0
  77. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_vast_runner.py +4 -2
  78. freesolo_flash_dev-1.2.48/tests/test_verl_child_plugins.py +745 -0
  79. freesolo_flash_dev-1.2.48/tests/test_verl_silence_watchdog.py +223 -0
  80. freesolo_flash_dev-1.2.48/tests/test_vl_warmstart_adapter_keys.py +161 -0
  81. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_wandb_link.py +4 -3
  82. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_warmstart_adapter_download.py +10 -12
  83. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_worker_init_heartbeat.py +82 -0
  84. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_worker_stack.py +11 -49
  85. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/uv.lock +1 -1
  86. freesolo_flash_dev-1.2.39/flash/engine/worker/model/lora.py +0 -118
  87. freesolo_flash_dev-1.2.39/flash/engine/worker/train/rl/child/plugin.py +0 -33
  88. freesolo_flash_dev-1.2.39/flash/engine/worker/train/rl/shims.py +0 -995
  89. freesolo_flash_dev-1.2.39/flash/engine/worker/verl/child_io.py +0 -999
  90. freesolo_flash_dev-1.2.39/tests/test_lora_rank_preflight.py +0 -311
  91. freesolo_flash_dev-1.2.39/tests/test_vl_warmstart_adapter_keys.py +0 -83
  92. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/.dockerignore +0 -0
  93. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/.env.example +0 -0
  94. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/.github/CODEOWNERS +0 -0
  95. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  96. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  97. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  98. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  99. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/.github/dependabot.yml +0 -0
  100. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/.github/workflows/auto-rebake.yml +0 -0
  101. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/.github/workflows/bake-kernel-cache.yml +0 -0
  102. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/.github/workflows/ci.yml +0 -0
  103. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/.github/workflows/main-source-guard.yml +0 -0
  104. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/.github/workflows/notify-tests-repo.yml +0 -0
  105. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/.github/workflows/publish-dev.yml +0 -0
  106. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/.github/workflows/publish-image.yml +0 -0
  107. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/.github/workflows/publish.yml +0 -0
  108. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/.github/workflows/version-parity.yml +0 -0
  109. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/.github/workflows/worker-image.yml +0 -0
  110. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/.gitignore +0 -0
  111. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/CODE_OF_CONDUCT.md +0 -0
  112. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/CONTRIBUTING.md +0 -0
  113. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/Dockerfile +0 -0
  114. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/Dockerfile.worker +0 -0
  115. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/LICENSE +0 -0
  116. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/NOTICE +0 -0
  117. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/README.md +0 -0
  118. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/SECURITY.md +0 -0
  119. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/SELF_HOSTING.md +0 -0
  120. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/build/kernel_cache/.gitignore +0 -0
  121. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/build/kernel_cache/.keep +0 -0
  122. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/deploy/infisical/README.md +0 -0
  123. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/deploy/infisical/entrypoint.sh +0 -0
  124. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/docker/Dockerfile.kernelcache +0 -0
  125. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/docker/Dockerfile.kernelcache.relayer +0 -0
  126. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/docker/bake_kernel_cache.py +0 -0
  127. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/docker/bake_pod_entry.py +0 -0
  128. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/docker/extract_cudart_fix.py +0 -0
  129. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/docker/kernel_fingerprint.py +0 -0
  130. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/docker/make_rp_handler.py +0 -0
  131. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/__init__.py +0 -0
  132. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/_internal/__init__.py +0 -0
  133. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/_internal/channel.py +0 -0
  134. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/_internal/diagnostics.py +0 -0
  135. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/_internal/fileio.py +0 -0
  136. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/_internal/logging.py +0 -0
  137. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/_internal/paths.py +0 -0
  138. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/adapters/__init__.py +0 -0
  139. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/adapters/artifacts.py +0 -0
  140. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/adapters/lora_rank.py +0 -0
  141. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/__init__.py +0 -0
  142. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/__main__.py +0 -0
  143. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/commands/__init__.py +0 -0
  144. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/commands/deploy.py +0 -0
  145. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/commands/env/__init__.py +0 -0
  146. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/commands/env/episode.py +0 -0
  147. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/commands/env/eval.py +0 -0
  148. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/commands/env/eval_args.py +0 -0
  149. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/commands/env/imports.py +0 -0
  150. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/commands/env/list.py +0 -0
  151. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/commands/env/push.py +0 -0
  152. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/commands/env/retained.py +0 -0
  153. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/commands/env/setup.py +0 -0
  154. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/commands/env/test.py +0 -0
  155. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/commands/env/test_evaluations.py +0 -0
  156. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/commands/env/test_params.py +0 -0
  157. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/commands/env/test_warnings.py +0 -0
  158. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/commands/prompt_budget.py +0 -0
  159. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/commands/traces.py +0 -0
  160. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/commands/train_cost.py +0 -0
  161. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/scaffold/TRAINING.md +0 -0
  162. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/scaffold/__init__.py +0 -0
  163. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/ui/__init__.py +0 -0
  164. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/ui/cost.py +0 -0
  165. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/ui/env_panels.py +0 -0
  166. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/ui/heartbeat.py +0 -0
  167. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/ui/render.py +0 -0
  168. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/ui/tables.py +0 -0
  169. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cli/ui/tty.py +0 -0
  170. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/client/__init__.py +0 -0
  171. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/client/config.py +0 -0
  172. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/client/freesolo_api.py +0 -0
  173. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/client/http.py +0 -0
  174. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/client/runtime_secrets.py +0 -0
  175. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/client/shapes.py +0 -0
  176. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/client/streaming.py +0 -0
  177. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/content/__init__.py +0 -0
  178. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/content/multimodal.py +0 -0
  179. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/content/structured_outputs.py +0 -0
  180. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/content/thinking.py +0 -0
  181. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/core/__init__.py +0 -0
  182. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/core/catalog.py +0 -0
  183. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cost/__init__.py +0 -0
  184. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cost/analytical.py +0 -0
  185. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cost/facts.py +0 -0
  186. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cost/spec.py +0 -0
  187. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/cost/types.py +0 -0
  188. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/__init__.py +0 -0
  189. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/plan/__init__.py +0 -0
  190. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/plan/kv_sizing.py +0 -0
  191. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/plan/model_config_probe.py +0 -0
  192. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/plan/prompt_budget.py +0 -0
  193. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/plan/recipe.py +0 -0
  194. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/plan/steps.py +0 -0
  195. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/plan/vram.py +0 -0
  196. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/profiling/__init__.py +0 -0
  197. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/profiling/dataset_profile.py +0 -0
  198. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/profiling/reasoning_render.py +0 -0
  199. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/profiling/sft_workload.py +0 -0
  200. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/profiling/tokenizer.py +0 -0
  201. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/profiling/workload_profile.py +0 -0
  202. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/result/__init__.py +0 -0
  203. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/result/accounting.py +0 -0
  204. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/result/rollout_samples.py +0 -0
  205. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/__main__.py +0 -0
  206. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/entry/__init__.py +0 -0
  207. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/entry/opd.py +0 -0
  208. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/entry/rl.py +0 -0
  209. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/entry/sft.py +0 -0
  210. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/io/__init__.py +0 -0
  211. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/io/hf.py +0 -0
  212. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/io/prefetch.py +0 -0
  213. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/io/wandb_log.py +0 -0
  214. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/model/__init__.py +0 -0
  215. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/model/decoding.py +0 -0
  216. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/model/packing.py +0 -0
  217. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/perf/__init__.py +0 -0
  218. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/perf/diagnostics.py +0 -0
  219. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/perf/lifecycle.py +0 -0
  220. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/perf/liger.py +0 -0
  221. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/perf/memory.py +0 -0
  222. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/runtime/__init__.py +0 -0
  223. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
  224. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
  225. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/runtime/rng.py +0 -0
  226. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/score_batcher.py +0 -0
  227. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/teacher/__init__.py +0 -0
  228. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/teacher/encoding.py +0 -0
  229. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
  230. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/__init__.py +0 -0
  231. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/core/__init__.py +0 -0
  232. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/core/child/__init__.py +0 -0
  233. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/core/child/glue.py +0 -0
  234. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/core/step_timing.py +0 -0
  235. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/finalize.py +0 -0
  236. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/opd/__init__.py +0 -0
  237. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/opd/child/__init__.py +0 -0
  238. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/opd/child/structured.py +0 -0
  239. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/opd/gkd.py +0 -0
  240. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
  241. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/opd/prompts.py +0 -0
  242. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/opd/reporting.py +0 -0
  243. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/opd/validation.py +0 -0
  244. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/rl/__init__.py +0 -0
  245. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/rl/child/__init__.py +0 -0
  246. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/rl/config.py +0 -0
  247. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/rl/scoring.py +0 -0
  248. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/rl/single_turn.py +0 -0
  249. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/rl/verl_config.py +0 -0
  250. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/train/sft/__init__.py +0 -0
  251. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/verl/__init__.py +0 -0
  252. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/verl/capabilities.py +0 -0
  253. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker/verl/parallelism.py +0 -0
  254. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/engine/worker_entrypoint.py +0 -0
  255. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/envs/__init__.py +0 -0
  256. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/envs/adapter.py +0 -0
  257. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/envs/base.py +0 -0
  258. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/envs/cache_security.py +0 -0
  259. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/envs/dataset_selection.py +0 -0
  260. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/envs/evaluations.py +0 -0
  261. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/envs/identity.py +0 -0
  262. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/envs/loader.py +0 -0
  263. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/envs/namespace_listing.py +0 -0
  264. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/envs/package/__init__.py +0 -0
  265. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/envs/package/limits.py +0 -0
  266. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/envs/package/unpack.py +0 -0
  267. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/envs/pull.py +0 -0
  268. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/__init__.py +0 -0
  269. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/_lifecycle/__init__.py +0 -0
  270. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/_lifecycle/auth.py +0 -0
  271. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
  272. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
  273. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/_lifecycle/deadline.py +0 -0
  274. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/_lifecycle/http.py +0 -0
  275. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/_lifecycle/poll.py +0 -0
  276. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/_lifecycle/poll_instance.py +0 -0
  277. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/_lifecycle/provider.py +0 -0
  278. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/_lifecycle/worker.py +0 -0
  279. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/allocator.py +0 -0
  280. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/artifacts/__init__.py +0 -0
  281. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/artifacts/preload_runpod.py +0 -0
  282. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/artifacts/weight_cache.py +0 -0
  283. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/base.py +0 -0
  284. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/fit_errors.py +0 -0
  285. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/lambda_/__init__.py +0 -0
  286. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/lambda_/api.py +0 -0
  287. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/lambda_/auth.py +0 -0
  288. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/lambda_/gpus.py +0 -0
  289. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/lambda_/jobs/__init__.py +0 -0
  290. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/lambda_/jobs/builders.py +0 -0
  291. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/lambda_/jobs/reap.py +0 -0
  292. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/lambda_/preflight.py +0 -0
  293. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/lambda_/pricing.py +0 -0
  294. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/preflight.py +0 -0
  295. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/realized.py +0 -0
  296. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/runpod/__init__.py +0 -0
  297. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/runpod/api.py +0 -0
  298. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/runpod/auth.py +0 -0
  299. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/runpod/cost.py +0 -0
  300. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/runpod/gpus.py +0 -0
  301. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/runpod/job_execution.py +0 -0
  302. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/runpod/jobs.py +0 -0
  303. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/runpod/preflight.py +0 -0
  304. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/runpod/pricing.py +0 -0
  305. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/runpod/serverless/__init__.py +0 -0
  306. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/sharding.py +0 -0
  307. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/vast/__init__.py +0 -0
  308. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/vast/api.py +0 -0
  309. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/vast/auth.py +0 -0
  310. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/vast/jobs/__init__.py +0 -0
  311. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/vast/preflight.py +0 -0
  312. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/providers/vast/pricing.py +0 -0
  313. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/py.typed +0 -0
  314. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/__init__.py +0 -0
  315. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/artifacts.py +0 -0
  316. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/attempts.py +0 -0
  317. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/costs.py +0 -0
  318. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/deadlines.py +0 -0
  319. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/reconciliation.py +0 -0
  320. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/results/__init__.py +0 -0
  321. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/results/checkpoints.py +0 -0
  322. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/results/verified_revisions.py +0 -0
  323. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/status.py +0 -0
  324. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/submit.py +0 -0
  325. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/supervise/__init__.py +0 -0
  326. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/supervise/attach.py +0 -0
  327. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/supervise/deploy.py +0 -0
  328. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/supervise/lifecycle.py +0 -0
  329. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/supervise/recovery.py +0 -0
  330. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/supervise/retry_decision.py +0 -0
  331. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/supervise/seed_submission.py +0 -0
  332. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/supervise/transitions.py +0 -0
  333. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/runner/weight_cache.py +0 -0
  334. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/schema/__init__.py +0 -0
  335. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/schema/fields.py +0 -0
  336. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/serve/__init__.py +0 -0
  337. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/serve/adapter_check.py +0 -0
  338. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/serve/deploy.py +0 -0
  339. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/serve/errors.py +0 -0
  340. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/serve/export.py +0 -0
  341. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/serve/preflight.py +0 -0
  342. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/serve/responses.py +0 -0
  343. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/serve/streaming.py +0 -0
  344. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/serve/thinking.py +0 -0
  345. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/serve/urls.py +0 -0
  346. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/__init__.py +0 -0
  347. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/__main__.py +0 -0
  348. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/app.py +0 -0
  349. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/billing/__init__.py +0 -0
  350. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/billing/charges.py +0 -0
  351. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/billing/retry.py +0 -0
  352. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/domain/__init__.py +0 -0
  353. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/domain/checkpoints.py +0 -0
  354. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/domain/environment_registry.py +0 -0
  355. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/domain/envs.py +0 -0
  356. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/domain/projects.py +0 -0
  357. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/domain/reconcile.py +0 -0
  358. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/domain/repo_cleanup.py +0 -0
  359. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/domain/run_registry.py +0 -0
  360. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/domain/teacher_broker.py +0 -0
  361. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/domain/teacher_errors.py +0 -0
  362. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/domain/teacher_requests.py +0 -0
  363. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/platform/__init__.py +0 -0
  364. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/platform/auth.py +0 -0
  365. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/platform/db.py +0 -0
  366. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/platform/deps.py +0 -0
  367. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/platform/internal_client.py +0 -0
  368. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/platform/locks.py +0 -0
  369. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/platform/runtime.py +0 -0
  370. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/routes/__init__.py +0 -0
  371. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/routes/envs.py +0 -0
  372. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/routes/meta.py +0 -0
  373. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/routes/runs.py +0 -0
  374. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/routes/serving.py +0 -0
  375. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/routes/serving_completion.py +0 -0
  376. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/routes/serving_revisions.py +0 -0
  377. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/routes/serving_smoke.py +0 -0
  378. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/server/routes/teacher.py +0 -0
  379. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/teacher/__init__.py +0 -0
  380. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/teacher/limits.py +0 -0
  381. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/flash/teacher/retry_contract.py +0 -0
  382. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/scripts/build_dev_dist.py +0 -0
  383. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/scripts/check_file_size.py +0 -0
  384. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/scripts/check_function_size.py +0 -0
  385. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/scripts/check_verl_pin_exists.py +0 -0
  386. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/scripts/scrub_history.sh +0 -0
  387. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/__init__.py +0 -0
  388. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/_helpers/__init__.py +0 -0
  389. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/_helpers/profile.py +0 -0
  390. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/_helpers/runner.py +0 -0
  391. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/_helpers/specs.py +0 -0
  392. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/_helpers/teacher.py +0 -0
  393. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/_helpers/vast.py +0 -0
  394. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/conftest.py +0 -0
  395. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/fixtures/math_eval.jsonl +0 -0
  396. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/fixtures/math_train.jsonl +0 -0
  397. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/live/__init__.py +0 -0
  398. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/live/conftest.py +0 -0
  399. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/live/test_lambda_live.py +0 -0
  400. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/live/test_runpod_live.py +0 -0
  401. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/live/test_sft_thinking_render_live.py +0 -0
  402. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/live/test_vast_live.py +0 -0
  403. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_accounting_coverage.py +0 -0
  404. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_agent_flash_cli_contract.py +0 -0
  405. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_algorithms.py +0 -0
  406. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_allocator.py +0 -0
  407. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_backend_jobspec_contract.py +0 -0
  408. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_bake_kernel_cache.py +0 -0
  409. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_base_model_provenance.py +0 -0
  410. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_billing_retry.py +0 -0
  411. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_build_context_contract.py +0 -0
  412. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_cancel_remote.py +0 -0
  413. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_catalog_consistency.py +0 -0
  414. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_catalog_only_models.py +0 -0
  415. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_charge_pricing.py +0 -0
  416. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_checkpoints.py +0 -0
  417. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_cli_commands.py +0 -0
  418. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_cli_commands_coverage.py +0 -0
  419. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_cli_credential_shadowing.py +0 -0
  420. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_cli_errors.py +0 -0
  421. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_cli_estimate.py +0 -0
  422. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_cli_gpus_flag.py +0 -0
  423. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_cli_help.py +0 -0
  424. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_cli_main_coverage.py +0 -0
  425. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_cli_managed.py +0 -0
  426. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_cli_render_coverage.py +0 -0
  427. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_cli_render_theme.py +0 -0
  428. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_cli_traces.py +0 -0
  429. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_cli_wandb_warning.py +0 -0
  430. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_client.py +0 -0
  431. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_client_import_purity.py +0 -0
  432. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_client_server_integration.py +0 -0
  433. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_client_stream_reads.py +0 -0
  434. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_config_env_vars.py +0 -0
  435. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_config_overrides.py +0 -0
  436. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_controlled_experiment_repairs.py +0 -0
  437. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_cost_analytical.py +0 -0
  438. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_cost_equation.py +0 -0
  439. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_cost_estimate.py +0 -0
  440. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_cost_hardware.py +0 -0
  441. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_cost_models.py +0 -0
  442. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_dataset_profile.py +0 -0
  443. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_deploy_alias_move_warning.py +0 -0
  444. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_deploy_latency.py +0 -0
  445. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_dev_channel.py +0 -0
  446. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_disk_gb.py +0 -0
  447. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_endpoint_name.py +0 -0
  448. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_env_cache_evict.py +0 -0
  449. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_env_delete.py +0 -0
  450. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_env_download.py +0 -0
  451. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_env_download_api.py +0 -0
  452. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_env_evaluations.py +0 -0
  453. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_env_list_api.py +0 -0
  454. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_env_list_cli.py +0 -0
  455. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_env_list_hub.py +0 -0
  456. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_env_no_install.py +0 -0
  457. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_env_publish.py +0 -0
  458. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_env_pull.py +0 -0
  459. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_env_pull_coverage.py +0 -0
  460. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_env_pull_loader_coverage.py +0 -0
  461. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_env_pull_managed_control_plane.py +0 -0
  462. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_env_push.py +0 -0
  463. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_env_rate_limit_resolve.py +0 -0
  464. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_env_ref_pinning.py +0 -0
  465. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_env_test.py +0 -0
  466. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_envs_coverage.py +0 -0
  467. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_export.py +0 -0
  468. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_flash_mvp.py +0 -0
  469. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_flashinfer_cache_dirs.py +0 -0
  470. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_freesolo_api_transport.py +0 -0
  471. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_github_urlopen_retry.py +0 -0
  472. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_gpu_type_single_field.py +0 -0
  473. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_gpus.py +0 -0
  474. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_grpo_resident_sizing.py +0 -0
  475. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_health_liveness.py +0 -0
  476. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_hf_retry.py +0 -0
  477. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_idle_endpoint_reaper.py +0 -0
  478. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_infisical_secrets.py +0 -0
  479. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_internal_client.py +0 -0
  480. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_kernel_cache.py +0 -0
  481. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_kernel_fingerprint.py +0 -0
  482. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_kv_util.py +0 -0
  483. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_lambda_api_coverage.py +0 -0
  484. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_logging.py +0 -0
  485. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_login_perms.py +0 -0
  486. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_lora_rank_coverage.py +0 -0
  487. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_managed_config_fields.py +0 -0
  488. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_managed_hf_repo.py +0 -0
  489. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_metrics_schema_agent_contract.py +0 -0
  490. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_mig_guard.py +0 -0
  491. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_multi_gpu_gate.py +0 -0
  492. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_named_reward_metrics.py +0 -0
  493. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_oom_escalate_gpu.py +0 -0
  494. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_opd.py +0 -0
  495. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_opd_limits.py +0 -0
  496. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_opd_multiturn_eos_boundary.py +0 -0
  497. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_opd_resume_safety.py +0 -0
  498. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_orchestrator_flash.py +0 -0
  499. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_packing.py +0 -0
  500. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_packing_coverage.py +0 -0
  501. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_parasail_teacher.py +0 -0
  502. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_poll_helpers.py +0 -0
  503. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_preflight.py +0 -0
  504. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_projects.py +0 -0
  505. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_prompt_budget.py +0 -0
  506. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_provider_preflight_coverage.py +0 -0
  507. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_provider_routing.py +0 -0
  508. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_provider_teardown_robustness.py +0 -0
  509. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_providers_symmetry.py +0 -0
  510. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_realized_cost.py +0 -0
  511. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_repo_cleanup.py +0 -0
  512. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_resolve_params_b.py +0 -0
  513. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_resume_on_retry.py +0 -0
  514. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_rollout_samples.py +0 -0
  515. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_runmgmt.py +0 -0
  516. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_runpod_api_delete.py +0 -0
  517. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_runpod_key_fingerprint.py +0 -0
  518. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_runpod_key_waterfall.py +0 -0
  519. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_serve.py +0 -0
  520. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_serve_reasoning_content.py +0 -0
  521. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_server_api.py +0 -0
  522. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_server_app_coverage.py +0 -0
  523. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_server_auth_singleflight.py +0 -0
  524. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_server_billing.py +0 -0
  525. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_server_checkpoints_coverage.py +0 -0
  526. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_server_db.py +0 -0
  527. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_server_envs_coverage.py +0 -0
  528. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_server_locks_coverage.py +0 -0
  529. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_server_standalone.py +0 -0
  530. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_serving_context_preflight.py +0 -0
  531. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_serving_contract.py +0 -0
  532. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_serving_schema_coverage.py +0 -0
  533. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_sft_chunked_nll.py +0 -0
  534. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_sft_example_selection.py +0 -0
  535. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_sft_gc_off.py +0 -0
  536. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_sft_max_context.py +0 -0
  537. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_sft_startup_block.py +0 -0
  538. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_sft_workload.py +0 -0
  539. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_spec_and_validation.py +0 -0
  540. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_step_floor.py +0 -0
  541. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_step_metrics.py +0 -0
  542. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_step_timing.py +0 -0
  543. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_structured_outputs.py +0 -0
  544. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_teacher_broker.py +0 -0
  545. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_teacher_encoding_contract.py +0 -0
  546. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_thinking_config.py +0 -0
  547. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_train_context_preflight.py +0 -0
  548. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_training_controls.py +0 -0
  549. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_type_comment_prose.py +0 -0
  550. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_vast_api.py +0 -0
  551. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_vast_api_coverage.py +0 -0
  552. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_vast_offers.py +0 -0
  553. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_vast_provider_coverage.py +0 -0
  554. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_verified_revisions.py +0 -0
  555. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_verifiers.py +0 -0
  556. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_verl_checkpoint_export.py +0 -0
  557. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_version.py +0 -0
  558. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_vram_architecture.py +0 -0
  559. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_wandb_naming.py +0 -0
  560. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_warmstart_cross_repo.py +0 -0
  561. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_warmstart_error_attribution.py +0 -0
  562. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_weight_cache.py +0 -0
  563. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_worker_dryrun.py +0 -0
  564. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_worker_hardexit.py +0 -0
  565. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_worker_image.py +0 -0
  566. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_worker_thinking.py +0 -0
  567. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_workflow_contracts.py +0 -0
  568. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_workload_profile.py +0 -0
  569. {freesolo_flash_dev-1.2.39 → freesolo_flash_dev-1.2.48}/tests/test_zero2_sharding_gate.py +0 -0
@@ -29,6 +29,17 @@ This file starts at 1.1.35. Earlier releases are not reconstructed here; use
29
29
 
30
30
  ### Fixed
31
31
 
32
+ - A GRPO or OPD run whose rollout actor exited hard no longer wedges on a paid GPU until the
33
+ wall-time limit. The actor's `os._exit` bypassed verl's own prompt handler, so the prompt
34
+ stayed `running` forever and verl's unbounded replay poll waited on it at ~0% utilization. The
35
+ child now writes durable failure evidence, marks the prompt failed, cleans up, and only then
36
+ exits, and replay sampling fails the step on an explicit failure tag or a positively dead
37
+ actor instead of returning a survivor-only batch that would silently train on fewer rollouts
38
+ than were collected. A child that reaches the fit loop and then stops producing distinct
39
+ output, while the parent has no teacher or environment work in flight, is torn down with a
40
+ named cause rather than running silently to the limit; repeated identical lines count as
41
+ silence, and authoritative OOM, host-RAM, and infrastructure evidence still classifies the
42
+ exit first.
32
43
  - `flash models deploy` now warns before it moves the shared `<run-id>` model id onto a
33
44
  different checkpoint. Every checkpoint of a run is served under that one id, so deploying
34
45
  `<run-id>/step-50` while `step-100` was live silently changed what `<run-id>` served for
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: freesolo-flash-dev
3
- Version: 1.2.39
3
+ Version: 1.2.48
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
@@ -18,10 +18,9 @@ def spec_payload(
18
18
  # wire without touching the digest, which is computed server-side from the reparsed spec.
19
19
  if spec.authored_gpu_count is None:
20
20
  out["gpu"] = {key: value for key, value in out["gpu"].items() if key != "count"}
21
- # [environment] pip is platform-managed and no longer travels in the payload: both provider
22
- # submit paths already resolve it from worker_pip_for_env when the spec carries none, so
23
- # sending it here only duplicated that constant, and the server's parser now rejects it as an
24
- # unauthorable key.
21
+ # [environment] pip DOES travel: it is the author's own scorer dependencies, which only they can
22
+ # declare, and the submit paths append it to worker_pip_for_env rather than replacing it. What
23
+ # travels is the extra requirements, not the worker's own.
25
24
  if authored_train_keys is not None:
26
25
  out["train"] = {
27
26
  key: value for key, value in out["train"].items() if key in authored_train_keys