agentinputlab 0.1.0a1__py3-none-any.whl
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.
- agentinputlab/__init__.py +28 -0
- agentinputlab/algorithms/__init__.py +6 -0
- agentinputlab/algorithms/acquire/__init__.py +145 -0
- agentinputlab/algorithms/acquire/adaptive_rag/__init__.py +43 -0
- agentinputlab/algorithms/acquire/adaptive_rag/replay.py +367 -0
- agentinputlab/algorithms/acquire/adaptive_rag/runtime.py +1202 -0
- agentinputlab/algorithms/acquire/adaptive_rag_common_support.py +542 -0
- agentinputlab/algorithms/acquire/hyde.py +296 -0
- agentinputlab/algorithms/acquire/hyde_controlled.py +200 -0
- agentinputlab/algorithms/acquire/hyde_external.py +148 -0
- agentinputlab/algorithms/acquire/ircot.py +28 -0
- agentinputlab/algorithms/acquire/ircot_common_support.py +478 -0
- agentinputlab/algorithms/acquire/ircot_native.py +355 -0
- agentinputlab/algorithms/acquire/ircot_replay.py +327 -0
- agentinputlab/algorithms/acquire/qrag/__init__.py +79 -0
- agentinputlab/algorithms/acquire/qrag/bridge.py +828 -0
- agentinputlab/algorithms/acquire/qrag/common_support.py +891 -0
- agentinputlab/algorithms/acquire/qrag/native_axis.py +71 -0
- agentinputlab/algorithms/acquire/qrag/reader_adapter.py +139 -0
- agentinputlab/algorithms/acquire/r2ag/__init__.py +57 -0
- agentinputlab/algorithms/acquire/r2ag/bridge.py +1312 -0
- agentinputlab/algorithms/acquire/r2ag/common_support.py +1029 -0
- agentinputlab/algorithms/acquire/r2ag/socket_runtime.py +255 -0
- agentinputlab/algorithms/clarify/__init__.py +61 -0
- agentinputlab/algorithms/clarify/_structured.py +64 -0
- agentinputlab/algorithms/clarify/active_task_disambiguation.py +371 -0
- agentinputlab/algorithms/clarify/ask_or_assume/__init__.py +17 -0
- agentinputlab/algorithms/clarify/ask_or_assume/monitor.py +410 -0
- agentinputlab/algorithms/clarify/future_turns.py +379 -0
- agentinputlab/algorithms/clarify/udcs.py +255 -0
- agentinputlab/algorithms/clarify/udcs_deterministic.py +196 -0
- agentinputlab/algorithms/curate/__init__.py +65 -0
- agentinputlab/algorithms/curate/acon/__init__.py +27 -0
- agentinputlab/algorithms/curate/acon/common.py +284 -0
- agentinputlab/algorithms/curate/acon/common_support.py +136 -0
- agentinputlab/algorithms/curate/acon/history_bridge.py +309 -0
- agentinputlab/algorithms/curate/acon/observation_bridge.py +290 -0
- agentinputlab/algorithms/curate/llmlingua/__init__.py +30 -0
- agentinputlab/algorithms/curate/llmlingua/adapters.py +537 -0
- agentinputlab/algorithms/curate/llmlingua/budget.py +48 -0
- agentinputlab/algorithms/curate/llmlingua/controlled.py +175 -0
- agentinputlab/algorithms/curate/llmlingua/multilingual.py +105 -0
- agentinputlab/algorithms/curate/llmlingua/span_map.py +167 -0
- agentinputlab/algorithms/curate/recomp/__init__.py +47 -0
- agentinputlab/algorithms/curate/recomp/external.py +1129 -0
- agentinputlab/algorithms/curate/recomp/selective.py +304 -0
- agentinputlab/algorithms/decompose/__init__.py +107 -0
- agentinputlab/algorithms/decompose/decomp/__init__.py +53 -0
- agentinputlab/algorithms/decompose/decomp/common_support.py +478 -0
- agentinputlab/algorithms/decompose/decomp/planner_component.py +199 -0
- agentinputlab/algorithms/decompose/decomp/worker_bridge.py +416 -0
- agentinputlab/algorithms/decompose/llm_compiler/__init__.py +35 -0
- agentinputlab/algorithms/decompose/llm_compiler/bridge.py +520 -0
- agentinputlab/algorithms/decompose/llm_compiler/common_support.py +504 -0
- agentinputlab/algorithms/decompose/plan_and_budget/__init__.py +43 -0
- agentinputlab/algorithms/decompose/plan_and_budget/cached_soft_budget.py +362 -0
- agentinputlab/algorithms/decompose/plan_and_budget/decomposer_component.py +107 -0
- agentinputlab/algorithms/decompose/plan_and_budget/full.py +205 -0
- agentinputlab/algorithms/decompose/plan_and_budget/hard_cap.py +246 -0
- agentinputlab/algorithms/decompose/plan_and_budget/regenerated_soft_budget.py +448 -0
- agentinputlab/algorithms/decompose/plan_and_solve/__init__.py +33 -0
- agentinputlab/algorithms/decompose/plan_and_solve/plan_component.py +192 -0
- agentinputlab/algorithms/decompose/plan_and_solve/ps_prompt.py +127 -0
- agentinputlab/algorithms/decompose/self_ask/__init__.py +27 -0
- agentinputlab/algorithms/decompose/self_ask/loop.py +362 -0
- agentinputlab/algorithms/decompose/self_ask/planner_component.py +117 -0
- agentinputlab/algorithms/reformulate/__init__.py +85 -0
- agentinputlab/algorithms/reformulate/infocqr/__init__.py +40 -0
- agentinputlab/algorithms/reformulate/infocqr/cache_replay.py +362 -0
- agentinputlab/algorithms/reformulate/infocqr/external.py +675 -0
- agentinputlab/algorithms/reformulate/infocqr/student.py +189 -0
- agentinputlab/algorithms/reformulate/query2doc/__init__.py +42 -0
- agentinputlab/algorithms/reformulate/query2doc/controlled_live.py +190 -0
- agentinputlab/algorithms/reformulate/query2doc/models.py +95 -0
- agentinputlab/algorithms/reformulate/query2doc/official_cached.py +335 -0
- agentinputlab/algorithms/reformulate/query2doc/querygym_bridge.py +223 -0
- agentinputlab/algorithms/reformulate/query2doc/querygym_runtime.py +326 -0
- agentinputlab/algorithms/reformulate/reformer/__init__.py +23 -0
- agentinputlab/algorithms/reformulate/reformer/external.py +417 -0
- agentinputlab/algorithms/reformulate/rrr.py +696 -0
- agentinputlab/annotation/__init__.py +5 -0
- agentinputlab/annotation/independent.py +428 -0
- agentinputlab/annotation/server.py +233 -0
- agentinputlab/annotation/static/app.js +121 -0
- agentinputlab/annotation/static/index.html +60 -0
- agentinputlab/annotation/static/review.css +2 -0
- agentinputlab/annotation/static/review.html +10 -0
- agentinputlab/annotation/static/review.js +11 -0
- agentinputlab/annotation/static/styles.css +55 -0
- agentinputlab/annotation/store.py +444 -0
- agentinputlab/api.py +368 -0
- agentinputlab/artifacts/__init__.py +15 -0
- agentinputlab/artifacts/json_file.py +104 -0
- agentinputlab/artifacts/manifest.py +98 -0
- agentinputlab/artifacts/store.py +157 -0
- agentinputlab/backends/__init__.py +98 -0
- agentinputlab/backends/embedding/__init__.py +25 -0
- agentinputlab/backends/embedding/base.py +145 -0
- agentinputlab/backends/embedding/callable.py +75 -0
- agentinputlab/backends/embedding/replay.py +129 -0
- agentinputlab/backends/llm/__init__.py +31 -0
- agentinputlab/backends/llm/base.py +149 -0
- agentinputlab/backends/llm/callable.py +108 -0
- agentinputlab/backends/llm/decomp_completion.py +88 -0
- agentinputlab/backends/llm/final_content_stop.py +72 -0
- agentinputlab/backends/llm/gpt_oss_final_channel.py +84 -0
- agentinputlab/backends/llm/openai_compatible.py +332 -0
- agentinputlab/backends/llm/transformers.py +171 -0
- agentinputlab/backends/retrieval/__init__.py +35 -0
- agentinputlab/backends/retrieval/base.py +50 -0
- agentinputlab/backends/retrieval/dense.py +777 -0
- agentinputlab/backends/retrieval/memory.py +119 -0
- agentinputlab/backends/retrieval/sqlite_fts.py +155 -0
- agentinputlab/backends/user/__init__.py +15 -0
- agentinputlab/backends/user/base.py +66 -0
- agentinputlab/backends/user/callable.py +54 -0
- agentinputlab/backends/user/replay.py +89 -0
- agentinputlab/backends/vector.py +38 -0
- agentinputlab/benchmarks/__init__.py +246 -0
- agentinputlab/benchmarks/acquisition.py +106 -0
- agentinputlab/benchmarks/ale.py +540 -0
- agentinputlab/benchmarks/appworld_ul.py +669 -0
- agentinputlab/benchmarks/assets.py +226 -0
- agentinputlab/benchmarks/base.py +68 -0
- agentinputlab/benchmarks/beir_archive.py +235 -0
- agentinputlab/benchmarks/beir_sample.py +269 -0
- agentinputlab/benchmarks/bfcl_native.py +245 -0
- agentinputlab/benchmarks/bfcl_v3.py +607 -0
- agentinputlab/benchmarks/cache.py +218 -0
- agentinputlab/benchmarks/clariq.py +203 -0
- agentinputlab/benchmarks/data/registry.json +321 -0
- agentinputlab/benchmarks/data/smoke_assets.json +511 -0
- agentinputlab/benchmarks/data/statebench_v0_8_1_task_ids.json +475 -0
- agentinputlab/benchmarks/data/toolsandbox_165848b_scenario_names.json +1 -0
- agentinputlab/benchmarks/execution.py +1111 -0
- agentinputlab/benchmarks/interactive.py +257 -0
- agentinputlab/benchmarks/ir_query.py +204 -0
- agentinputlab/benchmarks/longbench.py +203 -0
- agentinputlab/benchmarks/paired_replay.py +479 -0
- agentinputlab/benchmarks/preprocess.py +2313 -0
- agentinputlab/benchmarks/production.py +236 -0
- agentinputlab/benchmarks/qa.py +963 -0
- agentinputlab/benchmarks/registry.py +110 -0
- agentinputlab/benchmarks/retrieval.py +459 -0
- agentinputlab/benchmarks/runtime.py +509 -0
- agentinputlab/benchmarks/statebench.py +938 -0
- agentinputlab/benchmarks/tau3.py +725 -0
- agentinputlab/benchmarks/toolsandbox.py +626 -0
- agentinputlab/benchmarks/trec_dl_sample.py +263 -0
- agentinputlab/campaign.py +654 -0
- agentinputlab/campaign_runner.py +953 -0
- agentinputlab/cli/__init__.py +6 -0
- agentinputlab/cli/main.py +933 -0
- agentinputlab/connectors/__init__.py +46 -0
- agentinputlab/connectors/knowledge/__init__.py +4 -0
- agentinputlab/connectors/tools/__init__.py +30 -0
- agentinputlab/connectors/tools/base.py +57 -0
- agentinputlab/connectors/tools/mcp.py +222 -0
- agentinputlab/connectors/tools/memory.py +41 -0
- agentinputlab/connectors/tools/openapi.py +695 -0
- agentinputlab/connectors/tools/schema.py +102 -0
- agentinputlab/contracts/__init__.py +91 -0
- agentinputlab/contracts/availability.py +24 -0
- agentinputlab/contracts/dependency.py +58 -0
- agentinputlab/contracts/enums.py +82 -0
- agentinputlab/contracts/errors.py +63 -0
- agentinputlab/contracts/evidence.py +43 -0
- agentinputlab/contracts/intent.py +110 -0
- agentinputlab/contracts/lifecycle.py +164 -0
- agentinputlab/contracts/patch.py +167 -0
- agentinputlab/contracts/serialization.py +93 -0
- agentinputlab/contracts/state.py +127 -0
- agentinputlab/contracts/trace.py +59 -0
- agentinputlab/contracts/worker.py +42 -0
- agentinputlab/core/__init__.py +7 -0
- agentinputlab/data/__init__.py +32 -0
- agentinputlab/data/checksums.py +9 -0
- agentinputlab/data/downloader.py +235 -0
- agentinputlab/data/http.py +171 -0
- agentinputlab/data/index.py +21 -0
- agentinputlab/data/overlap.py +28 -0
- agentinputlab/data/preprocess.py +32 -0
- agentinputlab/data/storage.py +57 -0
- agentinputlab/data/trec_sample.py +427 -0
- agentinputlab/evaluation/__init__.py +5 -0
- agentinputlab/evaluation/outcomes.py +32 -0
- agentinputlab/experiments/__init__.py +278 -0
- agentinputlab/experiments/analysis.py +981 -0
- agentinputlab/experiments/artifacts.py +687 -0
- agentinputlab/experiments/automatic_measurement.py +678 -0
- agentinputlab/experiments/auxiliary_matrix.py +203 -0
- agentinputlab/experiments/bindings.py +430 -0
- agentinputlab/experiments/blueprints.py +147 -0
- agentinputlab/experiments/builders/__init__.py +45 -0
- agentinputlab/experiments/builders/executable_external_payload.py +423 -0
- agentinputlab/experiments/builders/external_process_arena.py +1018 -0
- agentinputlab/experiments/builders/registry_intervention.py +463 -0
- agentinputlab/experiments/cli.py +158 -0
- agentinputlab/experiments/controls.py +340 -0
- agentinputlab/experiments/driver_guard.py +205 -0
- agentinputlab/experiments/drivers/__init__.py +89 -0
- agentinputlab/experiments/drivers/external_arena.py +2908 -0
- agentinputlab/experiments/drivers/method_process.py +662 -0
- agentinputlab/experiments/drivers/parity_process.py +1484 -0
- agentinputlab/experiments/drivers/static_production.py +1574 -0
- agentinputlab/experiments/executor.py +448 -0
- agentinputlab/experiments/loader.py +605 -0
- agentinputlab/experiments/measurement.py +675 -0
- agentinputlab/experiments/paper_analysis.py +1818 -0
- agentinputlab/experiments/parity_identity.py +605 -0
- agentinputlab/experiments/plan.py +277 -0
- agentinputlab/experiments/production_builders.py +3739 -0
- agentinputlab/experiments/readiness.py +432 -0
- agentinputlab/experiments/schema.py +514 -0
- agentinputlab/experiments/secrets.py +177 -0
- agentinputlab/experiments/stateful_analysis.py +1738 -0
- agentinputlab/experiments/transfer_analysis.py +1316 -0
- agentinputlab/experiments/unseen_analysis.py +1025 -0
- agentinputlab/integrations/__init__.py +1 -0
- agentinputlab/integrations/action_space/__init__.py +1 -0
- agentinputlab/integrations/external_workers/__init__.py +76 -0
- agentinputlab/integrations/external_workers/ace.py +431 -0
- agentinputlab/integrations/external_workers/base.py +181 -0
- agentinputlab/integrations/external_workers/decomp_live.py +249 -0
- agentinputlab/integrations/external_workers/decomp_planner.py +30 -0
- agentinputlab/integrations/external_workers/infocqr_student.py +280 -0
- agentinputlab/integrations/external_workers/ircot.py +576 -0
- agentinputlab/integrations/external_workers/llmcompiler_live.py +360 -0
- agentinputlab/integrations/external_workers/longllmlingua.py +162 -0
- agentinputlab/integrations/external_workers/method.py +314 -0
- agentinputlab/integrations/external_workers/process.py +678 -0
- agentinputlab/integrations/external_workers/supervisor.py +1071 -0
- agentinputlab/integrations/full_architecture/__init__.py +1 -0
- agentinputlab/integrations/full_architecture/hyde.py +212 -0
- agentinputlab/integrations/full_architecture/plan_and_budget.py +188 -0
- agentinputlab/integrations/live_history.py +222 -0
- agentinputlab/integrations/prompt_optimization/__init__.py +1 -0
- agentinputlab/integrations/training/__init__.py +1 -0
- agentinputlab/metrics/__init__.py +50 -0
- agentinputlab/metrics/catalog.py +313 -0
- agentinputlab/metrics/harm.py +95 -0
- agentinputlab/metrics/paired.py +40 -0
- agentinputlab/metrics/qa.py +76 -0
- agentinputlab/metrics/text.py +33 -0
- agentinputlab/metrics/third_party.py +161 -0
- agentinputlab/models/__init__.py +4 -0
- agentinputlab/observability/__init__.py +56 -0
- agentinputlab/observability/budget.py +316 -0
- agentinputlab/observability/instrumentation.py +754 -0
- agentinputlab/observability/models.py +403 -0
- agentinputlab/observability/monitor.py +380 -0
- agentinputlab/optimizers/__init__.py +1 -0
- agentinputlab/optimizers/clarify/__init__.py +12 -0
- agentinputlab/optimizers/context/__init__.py +22 -0
- agentinputlab/optimizers/decompose/__init__.py +64 -0
- agentinputlab/optimizers/evidence/__init__.py +22 -0
- agentinputlab/optimizers/rewrite/__init__.py +30 -0
- agentinputlab/parity/__init__.py +5 -0
- agentinputlab/parity/base.py +206 -0
- agentinputlab/production_campaign.py +763 -0
- agentinputlab/py.typed +1 -0
- agentinputlab/recipes/__init__.py +333 -0
- agentinputlab/recipes/ace.py +418 -0
- agentinputlab/recipes/ace_bfcl.py +273 -0
- agentinputlab/recipes/ace_common_support.py +169 -0
- agentinputlab/recipes/ace_native_plan.py +322 -0
- agentinputlab/recipes/ace_online.py +711 -0
- agentinputlab/recipes/ace_retrieval.py +330 -0
- agentinputlab/recipes/ace_statebench.py +382 -0
- agentinputlab/recipes/ace_tau.py +463 -0
- agentinputlab/recipes/ace_toolsandbox.py +432 -0
- agentinputlab/recipes/acon_guideline.py +22 -0
- agentinputlab/recipes/adaptive_rag.py +822 -0
- agentinputlab/recipes/llmlingua2_inference.py +146 -0
- agentinputlab/recipes/llmlingua2_training.py +796 -0
- agentinputlab/recipes/mce.py +1486 -0
- agentinputlab/recipes/mce_final.py +335 -0
- agentinputlab/recipes/mce_text_fit.py +499 -0
- agentinputlab/recipes/mce_text_only.py +298 -0
- agentinputlab/recipes/qrag.py +729 -0
- agentinputlab/recipes/qrag_inference.py +364 -0
- agentinputlab/recipes/r2ag_features.py +236 -0
- agentinputlab/recipes/r2ag_inference.py +503 -0
- agentinputlab/recipes/r2ag_training.py +948 -0
- agentinputlab/recipes/recomp_abstractive.py +592 -0
- agentinputlab/recipes/recomp_extractive.py +525 -0
- agentinputlab/recipes/reformer.py +17 -0
- agentinputlab/recipes/rqrag.py +1516 -0
- agentinputlab/recipes/rqrag_common_support.py +193 -0
- agentinputlab/recipes/rqrag_completion.py +147 -0
- agentinputlab/recipes/skillopt.py +462 -0
- agentinputlab/recipes/skillopt_common_support.py +154 -0
- agentinputlab/recipes/skillopt_environment.py +165 -0
- agentinputlab/recipes/skillopt_environment_cli.py +5 -0
- agentinputlab/recipes/skillopt_retrieval.py +188 -0
- agentinputlab/recipes/smartsearch.py +897 -0
- agentinputlab/recipes/smartsearch_curriculum.py +283 -0
- agentinputlab/recipes/smartsearch_grpo_contracts.py +58 -0
- agentinputlab/recipes/smartsearch_grpo_data.py +314 -0
- agentinputlab/recipes/smartsearch_grpo_meter.py +324 -0
- agentinputlab/recipes/smartsearch_grpo_prefix.py +144 -0
- agentinputlab/recipes/smartsearch_grpo_rollout.py +119 -0
- agentinputlab/recipes/smartsearch_grpo_tools.py +364 -0
- agentinputlab/recipes/smartsearch_grpo_training.py +305 -0
- agentinputlab/recipes/smartsearch_grpo_transport.py +248 -0
- agentinputlab/recipes/smartsearch_grpo_worker.py +364 -0
- agentinputlab/recipes/smartsearch_inference.py +524 -0
- agentinputlab/recipes/smartsearch_native_data.py +172 -0
- agentinputlab/recipes/smartsearch_policy.py +616 -0
- agentinputlab/recipes/smartsearch_policy_worker.py +9 -0
- agentinputlab/recipes/smartsearch_sampling.py +232 -0
- agentinputlab/recipes/smartsearch_teacher.py +203 -0
- agentinputlab/recipes/smartsearch_training.py +265 -0
- agentinputlab/registry/__init__.py +46 -0
- agentinputlab/registry/beta.py +727 -0
- agentinputlab/registry/data/algorithms.json +1959 -0
- agentinputlab/registry/data/auxiliary_method_profiles.json +34 -0
- agentinputlab/registry/loader.py +100 -0
- agentinputlab/registry/result_manifest.py +184 -0
- agentinputlab/registry/runtime.py +195 -0
- agentinputlab/registry/schema.py +449 -0
- agentinputlab/runner/__init__.py +30 -0
- agentinputlab/runner/balance.py +248 -0
- agentinputlab/runner/cache.py +135 -0
- agentinputlab/runner/composite.py +130 -0
- agentinputlab/runner/engine.py +285 -0
- agentinputlab/runner/runtime_guard.py +268 -0
- agentinputlab/runner/worker.py +80 -0
- agentinputlab/runtime_bootstrap.py +288 -0
- agentinputlab/selectors/__init__.py +196 -0
- agentinputlab/selectors/advanced.py +1514 -0
- agentinputlab/selectors/artifacts.py +1087 -0
- agentinputlab/selectors/base.py +112 -0
- agentinputlab/selectors/campaigns.py +1893 -0
- agentinputlab/selectors/catalog.py +86 -0
- agentinputlab/selectors/discovery.py +1860 -0
- agentinputlab/selectors/evaluation.py +1348 -0
- agentinputlab/selectors/features.py +383 -0
- agentinputlab/selectors/learned.py +502 -0
- agentinputlab/selectors/no_op.py +28 -0
- agentinputlab/selectors/outcome_table.py +475 -0
- agentinputlab/selectors/producer.py +853 -0
- agentinputlab/selectors/rules.py +109 -0
- agentinputlab/selectors/runtime.py +420 -0
- agentinputlab/studies/__init__.py +16 -0
- agentinputlab/studies/design.py +165 -0
- agentinputlab/studies/paired.py +322 -0
- agentinputlab/studio/__init__.py +6 -0
- agentinputlab/studio/campaigns.py +819 -0
- agentinputlab/studio/engine.py +1408 -0
- agentinputlab/studio/model_backends.py +425 -0
- agentinputlab/studio/prepared.py +410 -0
- agentinputlab/studio/server.py +613 -0
- agentinputlab/studio/static/app.js +397 -0
- agentinputlab/studio/static/campaigns.html +175 -0
- agentinputlab/studio/static/campaigns.js +426 -0
- agentinputlab/studio/static/index.html +192 -0
- agentinputlab/studio/static/result.html +103 -0
- agentinputlab/studio/static/result.js +273 -0
- agentinputlab/studio/static/styles.css +467 -0
- agentinputlab-0.1.0a1.data/data/share/agentinputlab/CITATION.cff +22 -0
- agentinputlab-0.1.0a1.dist-info/METADATA +392 -0
- agentinputlab-0.1.0a1.dist-info/RECORD +469 -0
- agentinputlab-0.1.0a1.dist-info/WHEEL +5 -0
- agentinputlab-0.1.0a1.dist-info/entry_points.txt +6 -0
- agentinputlab-0.1.0a1.dist-info/licenses/LICENSE +21 -0
- agentinputlab-0.1.0a1.dist-info/licenses/NOTICE +31 -0
- agentinputlab-0.1.0a1.dist-info/licenses/THIRD_PARTY_NOTICES.md +94 -0
- agentinputlab-0.1.0a1.dist-info/top_level.txt +2 -0
- workers/README.md +94 -0
- workers/ace/README.md +261 -0
- workers/ace/__init__.py +1 -0
- workers/ace/compatibility_manifest.json +39 -0
- workers/ace/driver.py +1682 -0
- workers/acon/README.md +215 -0
- workers/acon/__init__.py +5 -0
- workers/acon/compatibility_manifest.json +93 -0
- workers/acon/driver.py +1859 -0
- workers/acon/fitted.py +395 -0
- workers/acon/guideline.py +470 -0
- workers/acon/guideline_source_manifest.json +20 -0
- workers/adaptive_rag/README.md +96 -0
- workers/adaptive_rag/__init__.py +15 -0
- workers/adaptive_rag/compatibility_manifest.json +61 -0
- workers/adaptive_rag/driver.py +1470 -0
- workers/adaptive_rag/fixture_runtime.py +163 -0
- workers/adaptive_rag/runtime.py +252 -0
- workers/ask_or_assume/README.md +124 -0
- workers/ask_or_assume/__init__.py +1 -0
- workers/ask_or_assume/compatibility_manifest.json +36 -0
- workers/ask_or_assume/driver.py +1227 -0
- workers/decomp/README.md +133 -0
- workers/decomp/UPSTREAM_LICENSE.Apache-2.0.txt +201 -0
- workers/decomp/__init__.py +5 -0
- workers/decomp/compatibility_manifest.json +205 -0
- workers/decomp/driver.py +1015 -0
- workers/decomp/live.py +137 -0
- workers/decomp/runtime.py +231 -0
- workers/infocqr/README.md +106 -0
- workers/infocqr/__init__.py +1 -0
- workers/infocqr/compatibility_manifest.json +84 -0
- workers/infocqr/driver.py +1766 -0
- workers/ircot/README.md +167 -0
- workers/ircot/__init__.py +7 -0
- workers/ircot/compatibility_manifest.json +121 -0
- workers/ircot/controlled.py +457 -0
- workers/ircot/driver.py +1373 -0
- workers/ircot/fixture_bindings.json +39 -0
- workers/ircot/fixture_config.json +48 -0
- workers/ircot/fixture_prompt.txt +2 -0
- workers/ircot/native_qa.py +398 -0
- workers/ircot/qa_compatibility_manifest.json +57 -0
- workers/ircot/runtime.py +97 -0
- workers/llmcompiler/README.md +160 -0
- workers/llmcompiler/__init__.py +1 -0
- workers/llmcompiler/compatibility_manifest.json +45 -0
- workers/llmcompiler/driver.py +1514 -0
- workers/llmcompiler/export_prompts.py +74 -0
- workers/llmcompiler/live.py +174 -0
- workers/llmcompiler/patch_manifest.json +147 -0
- workers/mce/README.md +198 -0
- workers/mce/__init__.py +29 -0
- workers/mce/compatibility_manifest.json +115 -0
- workers/mce/driver.py +2585 -0
- workers/mce/final_eval.py +173 -0
- workers/official_arenas/README.md +25 -0
- workers/official_arenas/__init__.py +1 -0
- workers/official_arenas/capture_records.py +110 -0
- workers/official_arenas/driver.py +619 -0
- workers/official_arenas/protocol.py +334 -0
- workers/official_arenas/providers/__init__.py +1 -0
- workers/official_arenas/providers/_live_history.py +228 -0
- workers/official_arenas/providers/_message_compat.py +77 -0
- workers/official_arenas/providers/appworld_ul.py +196 -0
- workers/official_arenas/providers/fixture.py +112 -0
- workers/official_arenas/providers/statebench.py +960 -0
- workers/official_arenas/providers/tau3.py +1672 -0
- workers/official_arenas/providers/tau_retail.py +586 -0
- workers/official_arenas/providers/toolsandbox.py +1321 -0
- workers/official_arenas/providers/tooltalk.py +699 -0
- workers/official_arenas/retail_capture.py +188 -0
- workers/official_arenas/retail_driver.py +275 -0
- workers/qrag/README.md +172 -0
- workers/qrag/__init__.py +1 -0
- workers/qrag/compatibility_manifest.json +64 -0
- workers/qrag/driver.py +673 -0
- workers/r2ag/README.md +154 -0
- workers/r2ag/__init__.py +5 -0
- workers/r2ag/compatibility_manifest.json +55 -0
- workers/r2ag/driver.py +1287 -0
- workers/r2ag/feature_schema.json +8 -0
- workers/r2ag/runtime.py +589 -0
- workers/recomp/README.md +120 -0
- workers/recomp/__init__.py +1 -0
- workers/recomp/compatibility_manifest.json +43 -0
- workers/recomp/driver.py +1653 -0
- workers/reformer/README.md +125 -0
- workers/reformer/__init__.py +1 -0
- workers/reformer/compatibility_manifest.json +68 -0
- workers/reformer/driver.py +1459 -0
- workers/reformer/induction.py +457 -0
- workers/rrr/README.md +126 -0
- workers/rrr/__init__.py +1 -0
- workers/rrr/compatibility_manifest.json +57 -0
- workers/rrr/driver.py +1133 -0
- workers/smartsearch/README.md +331 -0
- workers/smartsearch/__init__.py +1 -0
- workers/smartsearch/compatibility_manifest.json +41 -0
- workers/smartsearch/driver.py +1643 -0
|
@@ -0,0 +1,616 @@
|
|
|
1
|
+
"""Native full-SFT / LoRA-DPO policy stages for SmartSearch's curriculum.
|
|
2
|
+
|
|
3
|
+
The pinned LLaMA-Factory owns data collation, losses, optimizer, scheduler and
|
|
4
|
+
checkpoint export. This module binds data/source/models, mounts fresh paths,
|
|
5
|
+
observes native steps and retains failure costs. GRPO/full-pipeline completion
|
|
6
|
+
is deliberately not claimed by these policy-stage APIs.
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import importlib
|
|
11
|
+
import importlib.metadata
|
|
12
|
+
import importlib.util
|
|
13
|
+
import json
|
|
14
|
+
import math
|
|
15
|
+
import os
|
|
16
|
+
import subprocess
|
|
17
|
+
import sys
|
|
18
|
+
import time
|
|
19
|
+
from collections.abc import Mapping
|
|
20
|
+
from contextlib import contextmanager, redirect_stderr, redirect_stdout
|
|
21
|
+
from dataclasses import dataclass
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
|
|
24
|
+
from agentinputlab.contracts import ExternalDependencyError, ValidationError
|
|
25
|
+
from agentinputlab.contracts.serialization import content_hash, to_jsonable
|
|
26
|
+
|
|
27
|
+
from .llmlingua2_training import _closed_files
|
|
28
|
+
from .qrag import _file, _sha
|
|
29
|
+
from .recomp_extractive import _LOCK, _scope
|
|
30
|
+
from .smartsearch_curriculum import _question_hash, verify_smartsearch_preparation_source
|
|
31
|
+
from .smartsearch_native_data import verify_smartsearch_native_data_source
|
|
32
|
+
|
|
33
|
+
POLICY_PROTOCOL = "agentinputlab.smartsearch.native_policy_stage.v1"
|
|
34
|
+
MODEL_SCHEMA = "agentinputlab.smartsearch.policy_snapshot.v1"
|
|
35
|
+
_CONFIGS = {
|
|
36
|
+
"sft": ("LLaMA-Factory/examples/train_full/qwen_full_sft.yaml",
|
|
37
|
+
"bc92534ece9249ebb54e02bfd6a7c22dd9424fa77a908a25e39936a68a91d471"),
|
|
38
|
+
"dpo": ("LLaMA-Factory/examples/train_lora/qwen_lora_dpo.yaml",
|
|
39
|
+
"1176f154ed14b5f9c0b9fec08424717689e92ca7ec2f47eb4712b0be0cc69394"),
|
|
40
|
+
"merge": ("LLaMA-Factory/examples/merge_lora/qwen_lora_dpo.yaml",
|
|
41
|
+
"c2176e4152139518bf75f371659b1e6970805307ff106e78dce7f93c39ea4cea"),
|
|
42
|
+
}
|
|
43
|
+
_ZERO3 = "LLaMA-Factory/examples/deepspeed/ds_z3_config.json"
|
|
44
|
+
_ZERO3_SHA = "6e2753c870561658babe45922114f14ad899d5e4cfb6deb38fe47935ee60dc6f"
|
|
45
|
+
_TRAIN_SOURCE = {
|
|
46
|
+
"LLaMA-Factory/src/llamafactory/train/tuner.py": "2e7b0bbd3db765ab140be8539f36c4c72e9bf53572ff43e719aed944fcde113a",
|
|
47
|
+
"LLaMA-Factory/src/llamafactory/train/sft/workflow.py": "eadb7829102c234d00464ca7895ea9bf33993d9503d7b713770012be4ef44735",
|
|
48
|
+
"LLaMA-Factory/src/llamafactory/train/sft/trainer.py": "66e2c3dbbe0acda54090edb6e29a9e3fbc0bd7ed7aaf808bacac61d624e3172b",
|
|
49
|
+
"LLaMA-Factory/src/llamafactory/train/dpo/workflow.py": "12e03b82dc61ac8c0149be9f2f6aef1919e4519d794e27ccf909970a740fc678",
|
|
50
|
+
"LLaMA-Factory/src/llamafactory/train/dpo/trainer.py": "f1af018d741a5f3a4cde2d654ce027f6bb4396bf88f1328d273ab669b71ac1d0",
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@dataclass(frozen=True, slots=True)
|
|
55
|
+
class SmartSearchPolicyFitControls:
|
|
56
|
+
seed: int = 17
|
|
57
|
+
max_optimizer_steps: int = 10000
|
|
58
|
+
max_data_bytes: int = 16 * 1024 * 1024
|
|
59
|
+
min_free_output_bytes: int = 32 * 1024**3
|
|
60
|
+
gpu_processes: int = 1
|
|
61
|
+
|
|
62
|
+
def __post_init__(self):
|
|
63
|
+
for name in ("seed", "max_optimizer_steps", "max_data_bytes", "min_free_output_bytes"):
|
|
64
|
+
value = getattr(self, name)
|
|
65
|
+
if type(value) is not int or value < (0 if name == "seed" else 1):
|
|
66
|
+
raise ValidationError("SmartSearch policy stage controls require positive integer caps")
|
|
67
|
+
if type(self.gpu_processes) is not int or not 1 <= self.gpu_processes <= 4:
|
|
68
|
+
raise ValidationError("SmartSearch policy fitting supports one to four operator-selected GPUs")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _save(root, name, value):
|
|
72
|
+
with (root / name).open("x", encoding="utf-8") as stream:
|
|
73
|
+
json.dump(to_jsonable(value), stream, ensure_ascii=False, sort_keys=True, allow_nan=False)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _source(checkout):
|
|
77
|
+
binding = dict(verify_smartsearch_preparation_source(checkout))
|
|
78
|
+
root = Path(binding["root"])
|
|
79
|
+
# These exact configs are part of the pinned upstream Git checkout. Never
|
|
80
|
+
# load caller-authored YAML with a Python object constructor.
|
|
81
|
+
checks = dict(_CONFIGS.values()) | {_ZERO3: _ZERO3_SHA} | _TRAIN_SOURCE
|
|
82
|
+
for relative, expected in checks.items():
|
|
83
|
+
path = _file(root / relative, "SmartSearch native training config")
|
|
84
|
+
if not path.is_relative_to(root) or _sha(path) != expected:
|
|
85
|
+
raise ExternalDependencyError("SmartSearch native training configuration changed")
|
|
86
|
+
binding["policy_configs"] = checks
|
|
87
|
+
return root, binding
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _model(root, manifest, manifest_sha256):
|
|
91
|
+
supplied = Path(root)
|
|
92
|
+
if supplied.is_symlink() or not supplied.is_dir():
|
|
93
|
+
raise ValidationError("SmartSearch policy requires a mounted regular model snapshot")
|
|
94
|
+
folder = supplied.resolve()
|
|
95
|
+
config = json.loads(_file(folder / "config.json", "policy model config").read_text())
|
|
96
|
+
tokenizer = json.loads(_file(folder / "tokenizer_config.json", "policy tokenizer config").read_text())
|
|
97
|
+
if config.get("quantization_config"):
|
|
98
|
+
raise ExternalDependencyError(
|
|
99
|
+
"SmartSearch native full-SFT/LoRA-merge pipeline does not support a quantized base; "
|
|
100
|
+
"no silent dequantization or replacement precision is applied"
|
|
101
|
+
)
|
|
102
|
+
if config.get("auto_map") or tokenizer.get("auto_map"):
|
|
103
|
+
raise ExternalDependencyError("SmartSearch policy fitting does not execute model remote code")
|
|
104
|
+
if not str(config.get("model_type", "")).startswith("qwen"):
|
|
105
|
+
raise ExternalDependencyError(
|
|
106
|
+
"SmartSearch's pinned policy configs use the Qwen template; another model family "
|
|
107
|
+
"requires an explicitly defined training variant, not an implicit prompt-template change"
|
|
108
|
+
)
|
|
109
|
+
folder, closure = _closed_files(folder, manifest, manifest_sha256, MODEL_SCHEMA)
|
|
110
|
+
names = closure["files"]
|
|
111
|
+
if not any(name.endswith(".safetensors") for name in names) or any(
|
|
112
|
+
name.endswith((".py", ".bin", ".pt", ".pkl", ".pickle")) for name in names
|
|
113
|
+
):
|
|
114
|
+
raise ValidationError("SmartSearch policy snapshot must use safe, code-free safetensors")
|
|
115
|
+
if "adapter_config.json" in names:
|
|
116
|
+
raise ValidationError("SmartSearch full policy snapshot cannot be an implicit LoRA adapter")
|
|
117
|
+
if not isinstance(closure.get("revision"), str) or closure["revision"].lower() in {"", "main", "latest", "head"}:
|
|
118
|
+
raise ValidationError("SmartSearch policy snapshot requires an immutable revision")
|
|
119
|
+
return folder, closure
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _curriculum(root, stage, byte_cap):
|
|
123
|
+
folder = Path(root)
|
|
124
|
+
if folder.is_symlink() or not folder.is_dir():
|
|
125
|
+
raise ValidationError("SmartSearch policy curriculum root must be a regular directory")
|
|
126
|
+
folder = folder.resolve()
|
|
127
|
+
manifest = json.loads(_file(folder / "manifest.json", "curriculum manifest").read_text())
|
|
128
|
+
artifact_id = manifest.pop("artifact_id", None)
|
|
129
|
+
if artifact_id != content_hash(manifest) or manifest.get("schema") != "agentinputlab.smartsearch.native-curriculum-data.v1":
|
|
130
|
+
raise ValidationError("SmartSearch curriculum artifact identity differs")
|
|
131
|
+
if manifest.get("rollout_provenance", {}).get("fixture_only"):
|
|
132
|
+
raise ValidationError("SmartSearch neural fitting cannot consume fixture-only rollouts")
|
|
133
|
+
name = f"{stage}.json"
|
|
134
|
+
path = _file(folder / name, "curriculum rows")
|
|
135
|
+
if path.stat().st_size > byte_cap or _sha(path) != manifest.get("outputs", {}).get(name):
|
|
136
|
+
raise ValidationError("SmartSearch native curriculum rows changed or exceed byte cap")
|
|
137
|
+
rows = json.loads(path.read_text())
|
|
138
|
+
if not isinstance(rows, list) or not rows:
|
|
139
|
+
raise ValidationError("SmartSearch native selection is empty; no replacement examples are manufactured")
|
|
140
|
+
audit = manifest.get("split_audit", {})
|
|
141
|
+
training_hashes = set(audit.get("train", {}).get("question_hashes", []))
|
|
142
|
+
heldout_hashes = set(audit.get("validation", {}).get("question_hashes", [])) | set(
|
|
143
|
+
audit.get("test", {}).get("question_hashes", []))
|
|
144
|
+
if not training_hashes or not audit.get("validation", {}).get("case_ids") or training_hashes & heldout_hashes:
|
|
145
|
+
raise ValidationError("SmartSearch curriculum lacks disjoint native train/validation/test audit")
|
|
146
|
+
keys = ("instruction", "input", "output") if stage == "sft" else ("instruction", "input", "chosen", "rejected")
|
|
147
|
+
for row in rows:
|
|
148
|
+
if not isinstance(row, dict) or any(not isinstance(row.get(k), str) or not row[k].strip() for k in keys):
|
|
149
|
+
raise ValidationError("SmartSearch native policy row is incomplete")
|
|
150
|
+
if _question_hash(row["input"]) not in training_hashes:
|
|
151
|
+
raise ValidationError("SmartSearch policy row is not a declared training question")
|
|
152
|
+
return rows, manifest, artifact_id
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def _native_config(source, stage, model, root, seed):
|
|
156
|
+
try:
|
|
157
|
+
import yaml
|
|
158
|
+
except ImportError as exc:
|
|
159
|
+
raise ExternalDependencyError("Install agentinputlab[yaml] to build native SmartSearch policy configs") from exc
|
|
160
|
+
config = yaml.safe_load((source / _CONFIGS[stage][0]).read_text())
|
|
161
|
+
if not isinstance(config, dict):
|
|
162
|
+
raise ExternalDependencyError("SmartSearch native policy configuration must be a mapping")
|
|
163
|
+
config.update(model_name_or_path=str(model), trust_remote_code=False)
|
|
164
|
+
if stage == "merge":
|
|
165
|
+
config.update(export_dir=str(root / "checkpoint"))
|
|
166
|
+
return config
|
|
167
|
+
# Only paths, explicit seed, cache/telemetry and create-only execution
|
|
168
|
+
# controls differ. Native loss/rank/LR/batches/epochs/cutoff/ZeRO stay intact.
|
|
169
|
+
config.update(
|
|
170
|
+
dataset=f"mine_{stage}", dataset_dir=str(root / "data"),
|
|
171
|
+
output_dir=str(root / "checkpoint"), deepspeed=str(source / _ZERO3),
|
|
172
|
+
seed=seed, data_seed=seed, overwrite_cache=False, overwrite_output_dir=False,
|
|
173
|
+
push_to_hub=False, report_to="none", resume_from_checkpoint=None,
|
|
174
|
+
)
|
|
175
|
+
return config
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def _source_import(source, native_data_source=None):
|
|
179
|
+
name = "llamafactory"
|
|
180
|
+
prefix = source / "LLaMA-Factory/src"
|
|
181
|
+
previous = list(sys.path)
|
|
182
|
+
if any(n == name or n.startswith(name + ".") for n in sys.modules):
|
|
183
|
+
raise ExternalDependencyError("Run each native SmartSearch policy stage in a fresh dedicated process")
|
|
184
|
+
sys.path.insert(0, str(prefix))
|
|
185
|
+
try:
|
|
186
|
+
if native_data_source is not None:
|
|
187
|
+
bound = verify_smartsearch_native_data_source(source, native_data_source["root"])
|
|
188
|
+
if bound != native_data_source:
|
|
189
|
+
raise ExternalDependencyError("SmartSearch native data supplement launch binding changed")
|
|
190
|
+
package = importlib.import_module(name)
|
|
191
|
+
if not Path(package.__file__).resolve().is_relative_to(prefix):
|
|
192
|
+
raise ExternalDependencyError("SmartSearch native package was shadowed")
|
|
193
|
+
# Mount this package only; never add an alternative framework root
|
|
194
|
+
# to sys.path or the original package's general search path.
|
|
195
|
+
data = Path(bound["root"]) / "data"
|
|
196
|
+
spec = importlib.util.spec_from_file_location(
|
|
197
|
+
"llamafactory.data", data / "__init__.py", submodule_search_locations=[str(data)])
|
|
198
|
+
module = importlib.util.module_from_spec(spec)
|
|
199
|
+
sys.modules[spec.name] = module
|
|
200
|
+
package.data = module
|
|
201
|
+
spec.loader.exec_module(module)
|
|
202
|
+
module = importlib.import_module("llamafactory.train.tuner")
|
|
203
|
+
if not Path(module.__file__).resolve().is_relative_to(prefix):
|
|
204
|
+
raise ExternalDependencyError("SmartSearch native trainer was shadowed by another installation")
|
|
205
|
+
return module
|
|
206
|
+
finally:
|
|
207
|
+
sys.path[:] = previous
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def _observer(counters, max_steps):
|
|
211
|
+
from transformers import TrainerCallback
|
|
212
|
+
|
|
213
|
+
class Observer(TrainerCallback):
|
|
214
|
+
def on_train_begin(self, args, state, control, **kwargs):
|
|
215
|
+
if state.max_steps < 1 or state.max_steps > max_steps:
|
|
216
|
+
raise ValidationError("SmartSearch native optimizer plan exceeds the caller's step cap")
|
|
217
|
+
counters["planned_optimizer_steps"] = state.max_steps
|
|
218
|
+
model = kwargs.get("model")
|
|
219
|
+
if model is None:
|
|
220
|
+
raise ExternalDependencyError("SmartSearch native trainer did not expose its policy")
|
|
221
|
+
|
|
222
|
+
def before(module, args, kwargs):
|
|
223
|
+
counters["forward_attempts"] += 1
|
|
224
|
+
inputs = kwargs.get("input_ids")
|
|
225
|
+
if inputs is None and args:
|
|
226
|
+
inputs = args[0]
|
|
227
|
+
counters["input_token_positions"] += int(inputs.numel()) if hasattr(inputs, "numel") else 0
|
|
228
|
+
|
|
229
|
+
def after(module, args, output):
|
|
230
|
+
counters["forward_responses"] += 1
|
|
231
|
+
|
|
232
|
+
self.before = model.register_forward_pre_hook(before, with_kwargs=True)
|
|
233
|
+
self.after = model.register_forward_hook(after)
|
|
234
|
+
|
|
235
|
+
def on_step_end(self, args, state, control, **kwargs):
|
|
236
|
+
counters["optimizer_steps"] = state.global_step
|
|
237
|
+
if state.global_step > max_steps:
|
|
238
|
+
raise ValidationError("SmartSearch native optimizer exceeded its declared step cap")
|
|
239
|
+
|
|
240
|
+
def on_log(self, args, state, control, logs=None, **kwargs):
|
|
241
|
+
if logs:
|
|
242
|
+
record = {}
|
|
243
|
+
for key, value in logs.items():
|
|
244
|
+
if isinstance(value, float) and not math.isfinite(value):
|
|
245
|
+
counters["nonfinite_native_metrics"] += 1
|
|
246
|
+
record[key] = repr(value)
|
|
247
|
+
elif isinstance(value, (float, int, str, bool)):
|
|
248
|
+
record[key] = value
|
|
249
|
+
counters["native_logs"].append(record)
|
|
250
|
+
|
|
251
|
+
def on_train_end(self, args, state, control, **kwargs):
|
|
252
|
+
self.before.remove()
|
|
253
|
+
self.after.remove()
|
|
254
|
+
|
|
255
|
+
return Observer()
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
@contextmanager
|
|
259
|
+
def _environment(root, seed):
|
|
260
|
+
overrides = {"HF_DATASETS_OFFLINE": "1", "HF_HUB_DISABLE_TELEMETRY": "1", "WANDB_MODE": "disabled"}
|
|
261
|
+
previous = {name: os.environ.get(name) for name in overrides}
|
|
262
|
+
try:
|
|
263
|
+
with _scope(root, seed):
|
|
264
|
+
os.environ.update(overrides)
|
|
265
|
+
yield
|
|
266
|
+
finally:
|
|
267
|
+
for name, value in previous.items():
|
|
268
|
+
if value is None:
|
|
269
|
+
os.environ.pop(name, None)
|
|
270
|
+
else:
|
|
271
|
+
os.environ[name] = value
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
@dataclass(frozen=True, slots=True)
|
|
275
|
+
class SmartSearchPolicyStageArtifact:
|
|
276
|
+
root: Path
|
|
277
|
+
artifact_id: str
|
|
278
|
+
stage: str
|
|
279
|
+
|
|
280
|
+
@property
|
|
281
|
+
def checkpoint(self):
|
|
282
|
+
return self.root / "checkpoint"
|
|
283
|
+
|
|
284
|
+
@classmethod
|
|
285
|
+
def load(cls, root):
|
|
286
|
+
supplied = Path(root)
|
|
287
|
+
if supplied.is_symlink() or not supplied.is_dir():
|
|
288
|
+
raise ValidationError("SmartSearch policy artifact root is invalid")
|
|
289
|
+
folder = supplied.resolve()
|
|
290
|
+
record = json.loads(_file(folder / "artifact.json", "policy artifact").read_text())
|
|
291
|
+
identity = record.pop("artifact_id", None)
|
|
292
|
+
if identity != content_hash(record) or record.get("protocol") != POLICY_PROTOCOL or record.get("stage") not in {"sft", "dpo", "merged_dpo"}:
|
|
293
|
+
raise ValidationError("SmartSearch policy artifact identity differs")
|
|
294
|
+
for key, name in (("fit_plan_sha256", "fit-plan.json"), ("fit_terminal_sha256", "fit-terminal.json")):
|
|
295
|
+
if _sha(_file(folder / name, "policy receipt")) != record.get(key):
|
|
296
|
+
raise ValidationError("SmartSearch policy artifact plan/terminal changed")
|
|
297
|
+
terminal = json.loads((folder / "fit-terminal.json").read_text())
|
|
298
|
+
if record["stage"] == "merged_dpo":
|
|
299
|
+
plan = json.loads((folder / "fit-plan.json").read_text())
|
|
300
|
+
if terminal.get("status") != "merged_candidate" or not plan.get("dpo_artifact_id"):
|
|
301
|
+
raise ValidationError("SmartSearch merged policy has no fitted adapter binding")
|
|
302
|
+
elif terminal.get("status") != "trained_candidate" or terminal.get("usage", {}).get("optimizer_steps", 0) < 1:
|
|
303
|
+
raise ValidationError("SmartSearch policy artifact has no completed optimizer step")
|
|
304
|
+
files = record.get("checkpoint_files")
|
|
305
|
+
if not isinstance(files, dict) or not files or not any(n.endswith(".safetensors") for n in files):
|
|
306
|
+
raise ValidationError("SmartSearch policy artifact has no safe checkpoint closure")
|
|
307
|
+
for name, digest in files.items():
|
|
308
|
+
if not isinstance(name, str) or Path(name).name != name or name in {".", ".."}:
|
|
309
|
+
raise ValidationError("SmartSearch policy checkpoint file path is unsafe")
|
|
310
|
+
if _sha(_file(folder / "checkpoint" / name, "policy checkpoint")) != digest:
|
|
311
|
+
raise ValidationError("SmartSearch policy checkpoint bytes changed")
|
|
312
|
+
return cls(folder, identity, record["stage"])
|
|
313
|
+
|
|
314
|
+
def materialize_snapshot(self, output_root):
|
|
315
|
+
"""Copy final SFT weights/tokenizer only; never pickle/optimizer state.
|
|
316
|
+
|
|
317
|
+
DPO is still an adapter and needs native merge before becoming a policy.
|
|
318
|
+
This explicit copy has a storage cost; the original training log and
|
|
319
|
+
checkpoints remain untouched.
|
|
320
|
+
"""
|
|
321
|
+
import shutil
|
|
322
|
+
|
|
323
|
+
current = self.load(self.root)
|
|
324
|
+
if current.stage == "dpo":
|
|
325
|
+
raise ValidationError("SmartSearch LoRA-DPO adapter must be natively merged before policy export")
|
|
326
|
+
record = json.loads((current.root / "artifact.json").read_text())
|
|
327
|
+
root = Path(output_root)
|
|
328
|
+
if root.exists() or root.is_symlink():
|
|
329
|
+
raise ValidationError("SmartSearch policy snapshot must be create-only")
|
|
330
|
+
root = root.resolve(strict=False)
|
|
331
|
+
if root.is_relative_to(current.root) or current.root.is_relative_to(root):
|
|
332
|
+
raise ValidationError("SmartSearch policy snapshot must not overlap the training artifact")
|
|
333
|
+
files = record["checkpoint_files"]
|
|
334
|
+
if not {"config.json", "tokenizer_config.json"} <= files.keys():
|
|
335
|
+
raise ValidationError("SmartSearch policy checkpoint lacks model/tokenizer configuration")
|
|
336
|
+
for name in files:
|
|
337
|
+
if Path(name).suffix not in {".safetensors", ".json", ".model", ".txt", ".jinja"}:
|
|
338
|
+
raise ValidationError("SmartSearch policy export refuses executable/binary payloads")
|
|
339
|
+
# Keep native training reports in the training artifact, not in the
|
|
340
|
+
# inference snapshot. The latter closes only model/tokenizer payloads.
|
|
341
|
+
hf_metadata = {"config.json", "generation_config.json", "tokenizer.json", "tokenizer_config.json",
|
|
342
|
+
"special_tokens_map.json", "added_tokens.json", "vocab.json", "vocab.txt", "merges.txt"}
|
|
343
|
+
files = {name: digest for name, digest in files.items() if name in hf_metadata or
|
|
344
|
+
name.endswith((".safetensors", ".safetensors.index.json", ".model", ".jinja"))}
|
|
345
|
+
parent = root.parent
|
|
346
|
+
while not parent.exists():
|
|
347
|
+
parent = parent.parent
|
|
348
|
+
required = sum((current.checkpoint / name).stat().st_size for name in files)
|
|
349
|
+
if shutil.disk_usage(parent).free < required:
|
|
350
|
+
raise ExternalDependencyError("SmartSearch policy snapshot copy lacks output capacity")
|
|
351
|
+
root.mkdir(parents=True, exist_ok=False)
|
|
352
|
+
(root / "model").mkdir()
|
|
353
|
+
for name, digest in files.items():
|
|
354
|
+
shutil.copyfile(current.checkpoint / name, root / "model" / name)
|
|
355
|
+
if _sha(root / "model" / name) != digest:
|
|
356
|
+
raise ValidationError("SmartSearch policy changed while copying its safe closure")
|
|
357
|
+
manifest = {"schema": MODEL_SCHEMA, "revision": "artifact:" + current.artifact_id,
|
|
358
|
+
"files": files, "training_artifact_id": current.artifact_id,
|
|
359
|
+
"toolkit_exporter_sha256": _sha(Path(__file__))}
|
|
360
|
+
_save(root, "model-manifest.json", manifest)
|
|
361
|
+
return {"model_root": str(root / "model"), "model_manifest": str(root / "model-manifest.json"),
|
|
362
|
+
"model_manifest_sha256": _sha(root / "model-manifest.json")}
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
class SmartSearchNativePolicyTraining:
|
|
366
|
+
"""Execute original LLaMA-Factory SFT/DPO; not the complete GRPO recipe."""
|
|
367
|
+
|
|
368
|
+
def __init__(self, controls=None):
|
|
369
|
+
self.controls = SmartSearchPolicyFitControls(**controls) if isinstance(controls, Mapping) else controls or SmartSearchPolicyFitControls()
|
|
370
|
+
if not isinstance(self.controls, SmartSearchPolicyFitControls):
|
|
371
|
+
raise ValidationError("SmartSearch policy fitting requires typed controls")
|
|
372
|
+
|
|
373
|
+
def fit(
|
|
374
|
+
self, *, stage, checkout, model_root, model_manifest, model_manifest_sha256,
|
|
375
|
+
curriculum_root, output_root, source_and_data_acknowledged=False, native_data_root=None,
|
|
376
|
+
):
|
|
377
|
+
if source_and_data_acknowledged is not True or stage not in {"sft", "dpo"}:
|
|
378
|
+
raise ValidationError("SmartSearch policy stage needs explicit source/data acknowledgement and sft/dpo")
|
|
379
|
+
source, source_binding = _source(checkout)
|
|
380
|
+
if native_data_root is None:
|
|
381
|
+
raise ExternalDependencyError("Prepare SmartSearch's pinned native data source and pass native_data_root")
|
|
382
|
+
native_data_source = verify_smartsearch_native_data_source(source, native_data_root)
|
|
383
|
+
model, closure = _model(model_root, model_manifest, model_manifest_sha256)
|
|
384
|
+
rows, curriculum, curriculum_id = _curriculum(curriculum_root, stage, self.controls.max_data_bytes)
|
|
385
|
+
root = Path(output_root)
|
|
386
|
+
if root.exists() or root.is_symlink():
|
|
387
|
+
raise ValidationError("SmartSearch policy output must be create-only; no automatic retry")
|
|
388
|
+
root = root.resolve(strict=False)
|
|
389
|
+
protected = (source, model, Path(curriculum_root).resolve())
|
|
390
|
+
if any(root.is_relative_to(p) or p.is_relative_to(root) for p in protected):
|
|
391
|
+
raise ValidationError("SmartSearch policy output must not overlap mounted assets")
|
|
392
|
+
import shutil
|
|
393
|
+
|
|
394
|
+
parent = root.parent
|
|
395
|
+
while not parent.exists():
|
|
396
|
+
parent = parent.parent
|
|
397
|
+
if shutil.disk_usage(parent).free < self.controls.min_free_output_bytes:
|
|
398
|
+
raise ExternalDependencyError("SmartSearch native policy output capacity is insufficient")
|
|
399
|
+
config = _native_config(source, stage, model, root, self.controls.seed)
|
|
400
|
+
root.mkdir(parents=True, exist_ok=False)
|
|
401
|
+
(root / "data").mkdir()
|
|
402
|
+
_save(root / "data", f"{stage}.json", rows)
|
|
403
|
+
dataset = {"file_name": f"{stage}.json", "columns": {"prompt": "instruction", "query": "input"}}
|
|
404
|
+
if stage == "sft":
|
|
405
|
+
dataset["columns"]["response"] = "output"
|
|
406
|
+
else:
|
|
407
|
+
dataset["ranking"] = True
|
|
408
|
+
dataset["columns"].update(chosen="chosen", rejected="rejected")
|
|
409
|
+
_save(root / "data", "dataset_info.json", {f"mine_{stage}": dataset})
|
|
410
|
+
versions = {}
|
|
411
|
+
for name in ("torch", "transformers", "trl", "datasets", "peft", "accelerate", "deepspeed"):
|
|
412
|
+
try:
|
|
413
|
+
versions[name] = importlib.metadata.version(name)
|
|
414
|
+
except importlib.metadata.PackageNotFoundError:
|
|
415
|
+
versions[name] = None
|
|
416
|
+
plan = {"protocol": POLICY_PROTOCOL, "stage": stage, "source": source_binding,
|
|
417
|
+
"native_data_source": native_data_source,
|
|
418
|
+
"controls": self.controls, "native_config": config, "model_manifest_sha256": model_manifest_sha256,
|
|
419
|
+
"model_revision": closure["revision"], "curriculum_artifact_id": curriculum_id,
|
|
420
|
+
"split_audit": curriculum["split_audit"], "training_only": True,
|
|
421
|
+
"native_loss_optimizer_scheduler_unchanged": True, "dependency_versions": versions,
|
|
422
|
+
"toolkit_policy_sha256": _sha(Path(__file__)),
|
|
423
|
+
"toolkit_worker_sha256": _sha(Path(__file__).with_name("smartsearch_policy_worker.py"))}
|
|
424
|
+
_save(root, "fit-plan.json", plan)
|
|
425
|
+
counters = {"rank_receipts": {}, "rank_usage_complete": False,
|
|
426
|
+
"forward_attempts": None, "forward_responses": None,
|
|
427
|
+
"optimizer_steps": None, "nonfinite_native_metrics": None}
|
|
428
|
+
started = time.monotonic()
|
|
429
|
+
try:
|
|
430
|
+
command = [sys.executable, "-m", "torch.distributed.run", "--standalone", "--nnodes=1",
|
|
431
|
+
f"--nproc_per_node={self.controls.gpu_processes}", "--max_restarts=0", "--module",
|
|
432
|
+
"agentinputlab.recipes.smartsearch_policy_worker", str(root),
|
|
433
|
+
_sha(root / "fit-plan.json")]
|
|
434
|
+
_save(root, "launch.json", {"argv": command, "no_automatic_retry": True,
|
|
435
|
+
"visible_devices": os.environ.get("CUDA_VISIBLE_DEVICES")})
|
|
436
|
+
with (root / "native.log").open("xb") as log:
|
|
437
|
+
process = subprocess.run(command, stdout=log, stderr=subprocess.STDOUT, check=False)
|
|
438
|
+
_collect_rank_usage(root, self.controls.gpu_processes, counters)
|
|
439
|
+
if process.returncode:
|
|
440
|
+
raise ExternalDependencyError(f"SmartSearch native distributed trainer exited {process.returncode}; see native.log")
|
|
441
|
+
if not counters["rank_usage_complete"] or any(
|
|
442
|
+
value.get("status") != "completed" for value in counters["rank_receipts"].values()
|
|
443
|
+
):
|
|
444
|
+
raise ExternalDependencyError("SmartSearch native rank receipts are incomplete")
|
|
445
|
+
if not counters["distributed_optimizer_step_agreement"]:
|
|
446
|
+
raise ExternalDependencyError("SmartSearch distributed ranks disagree on native optimizer steps")
|
|
447
|
+
checkpoint = root / "checkpoint"
|
|
448
|
+
tensors = [p for p in checkpoint.iterdir() if p.name.endswith(".safetensors")]
|
|
449
|
+
if counters["optimizer_steps"] < 1 or not tensors or any(p.is_symlink() for p in tensors):
|
|
450
|
+
raise ExternalDependencyError("SmartSearch native policy did not produce a trained safe checkpoint")
|
|
451
|
+
if counters["nonfinite_native_metrics"]:
|
|
452
|
+
raise ExternalDependencyError("SmartSearch native training recorded a non-finite loss")
|
|
453
|
+
files = {p.name: _sha(p) for p in checkpoint.iterdir()
|
|
454
|
+
if p.is_file() and p.suffix in {".safetensors", ".json", ".model", ".txt", ".jinja"}}
|
|
455
|
+
terminal = {"status": "trained_candidate", "stage": stage, "usage": counters,
|
|
456
|
+
"elapsed_seconds": time.monotonic() - started, "checkpoint_files": files,
|
|
457
|
+
"heldout_evaluation_completed": False, "full_sft_dpo_grpo_completed": False}
|
|
458
|
+
_save(root, "fit-terminal.json", terminal)
|
|
459
|
+
artifact = {"protocol": POLICY_PROTOCOL, "stage": stage,
|
|
460
|
+
"fit_plan_sha256": _sha(root / "fit-plan.json"),
|
|
461
|
+
"fit_terminal_sha256": _sha(root / "fit-terminal.json"),
|
|
462
|
+
"checkpoint_files": files, "base_model_manifest_sha256": model_manifest_sha256,
|
|
463
|
+
"source_commit": source_binding["source_commit"], "curriculum_artifact_id": curriculum_id}
|
|
464
|
+
artifact["artifact_id"] = content_hash(artifact)
|
|
465
|
+
_save(root, "artifact.json", artifact)
|
|
466
|
+
return SmartSearchPolicyStageArtifact.load(root)
|
|
467
|
+
except Exception as exc:
|
|
468
|
+
_collect_rank_usage(root, self.controls.gpu_processes, counters)
|
|
469
|
+
_save(root, "failed.json", {"error_type": type(exc).__name__, "error": str(exc),
|
|
470
|
+
"usage": counters, "elapsed_seconds": time.monotonic() - started,
|
|
471
|
+
"no_automatic_retry": True})
|
|
472
|
+
raise
|
|
473
|
+
|
|
474
|
+
def merge(
|
|
475
|
+
self, *, checkout, model_root, model_manifest, model_manifest_sha256,
|
|
476
|
+
dpo_artifact_root, output_root, source_and_data_acknowledged=False, native_data_root=None,
|
|
477
|
+
):
|
|
478
|
+
"""Native CPU LoRA merge with the exact SFT base; no new training."""
|
|
479
|
+
if source_and_data_acknowledged is not True:
|
|
480
|
+
raise ValidationError("SmartSearch native merge requires explicit source/data acknowledgement")
|
|
481
|
+
source, source_binding = _source(checkout)
|
|
482
|
+
if native_data_root is None:
|
|
483
|
+
raise ExternalDependencyError("Prepare SmartSearch's pinned native data source and pass native_data_root")
|
|
484
|
+
native_data_source = verify_smartsearch_native_data_source(source, native_data_root)
|
|
485
|
+
model, closure = _model(model_root, model_manifest, model_manifest_sha256)
|
|
486
|
+
adapter = SmartSearchPolicyStageArtifact.load(dpo_artifact_root)
|
|
487
|
+
record = json.loads((adapter.root / "artifact.json").read_text())
|
|
488
|
+
if adapter.stage != "dpo" or record["base_model_manifest_sha256"] != model_manifest_sha256:
|
|
489
|
+
raise ValidationError("SmartSearch DPO adapter and native merge base do not match")
|
|
490
|
+
root = Path(output_root)
|
|
491
|
+
if root.exists() or root.is_symlink():
|
|
492
|
+
raise ValidationError("SmartSearch native merge must use a new output directory")
|
|
493
|
+
root = root.resolve(strict=False)
|
|
494
|
+
if any(root.is_relative_to(p) or p.is_relative_to(root) for p in (source, model, adapter.root)):
|
|
495
|
+
raise ValidationError("SmartSearch native merge output overlaps a protected input")
|
|
496
|
+
config = _native_config(source, "merge", model, root, self.controls.seed)
|
|
497
|
+
config["adapter_name_or_path"] = str(adapter.checkpoint)
|
|
498
|
+
root.mkdir(parents=True, exist_ok=False)
|
|
499
|
+
controls = to_jsonable(self.controls)
|
|
500
|
+
controls["gpu_processes"] = 1 # original merge export_device=cpu
|
|
501
|
+
plan = {"protocol": POLICY_PROTOCOL, "operation": "merge", "source": source_binding,
|
|
502
|
+
"native_data_source": native_data_source,
|
|
503
|
+
"controls": controls, "native_config": config, "model_revision": closure["revision"],
|
|
504
|
+
"model_manifest_sha256": model_manifest_sha256, "dpo_artifact_id": adapter.artifact_id,
|
|
505
|
+
"toolkit_policy_sha256": _sha(Path(__file__)),
|
|
506
|
+
"toolkit_worker_sha256": _sha(Path(__file__).with_name("smartsearch_policy_worker.py"))}
|
|
507
|
+
_save(root, "fit-plan.json", plan)
|
|
508
|
+
usage = {"rank_receipts": {}, "rank_usage_complete": False, "forward_attempts": None,
|
|
509
|
+
"forward_responses": None, "optimizer_steps": None}
|
|
510
|
+
started = time.monotonic()
|
|
511
|
+
try:
|
|
512
|
+
command = [sys.executable, "-m", "agentinputlab.recipes.smartsearch_policy_worker",
|
|
513
|
+
str(root), _sha(root / "fit-plan.json")]
|
|
514
|
+
_save(root, "launch.json", {"argv": command, "no_automatic_retry": True, "export_device": "cpu"})
|
|
515
|
+
with (root / "native.log").open("xb") as log:
|
|
516
|
+
process = subprocess.run(command, stdout=log, stderr=subprocess.STDOUT, check=False)
|
|
517
|
+
_collect_rank_usage(root, 1, usage)
|
|
518
|
+
if process.returncode or not usage["rank_usage_complete"] or usage["rank_receipts"]["0"]["status"] != "completed":
|
|
519
|
+
raise ExternalDependencyError("SmartSearch native LoRA merge did not complete; see retained native logs")
|
|
520
|
+
checkpoint = root / "checkpoint"
|
|
521
|
+
files = {p.name: _sha(p) for p in checkpoint.iterdir()
|
|
522
|
+
if p.is_file() and not p.is_symlink() and p.suffix in {".safetensors", ".json", ".model", ".txt", ".jinja"}}
|
|
523
|
+
if not any(name.endswith(".safetensors") for name in files) or "config.json" not in files:
|
|
524
|
+
raise ExternalDependencyError("SmartSearch native merge did not export safe policy weights")
|
|
525
|
+
_save(root, "fit-terminal.json", {"status": "merged_candidate", "usage": usage,
|
|
526
|
+
"elapsed_seconds": time.monotonic() - started,
|
|
527
|
+
"full_sft_dpo_grpo_completed": False})
|
|
528
|
+
artifact = {"protocol": POLICY_PROTOCOL, "stage": "merged_dpo",
|
|
529
|
+
"fit_plan_sha256": _sha(root / "fit-plan.json"),
|
|
530
|
+
"fit_terminal_sha256": _sha(root / "fit-terminal.json"),
|
|
531
|
+
"checkpoint_files": files, "base_model_manifest_sha256": model_manifest_sha256,
|
|
532
|
+
"source_commit": source_binding["source_commit"], "dpo_artifact_id": adapter.artifact_id}
|
|
533
|
+
artifact["artifact_id"] = content_hash(artifact)
|
|
534
|
+
_save(root, "artifact.json", artifact)
|
|
535
|
+
return SmartSearchPolicyStageArtifact.load(root)
|
|
536
|
+
except Exception as exc:
|
|
537
|
+
_collect_rank_usage(root, 1, usage)
|
|
538
|
+
_save(root, "failed.json", {"error_type": type(exc).__name__, "error": str(exc), "usage": usage,
|
|
539
|
+
"elapsed_seconds": time.monotonic() - started, "no_automatic_retry": True})
|
|
540
|
+
raise
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
def _collect_rank_usage(root, world_size, counters):
|
|
544
|
+
records = {}
|
|
545
|
+
errors = []
|
|
546
|
+
expected_plan = _sha(root / "fit-plan.json")
|
|
547
|
+
for rank in range(world_size):
|
|
548
|
+
path = root / f"rank-{rank}-terminal.json"
|
|
549
|
+
if path.is_file() and not path.is_symlink():
|
|
550
|
+
try:
|
|
551
|
+
row = json.loads(path.read_text())
|
|
552
|
+
if row.get("rank") != rank or row.get("plan_sha256") != expected_plan or row.get("status") not in {"completed", "failed"}:
|
|
553
|
+
raise ValueError("rank/plan/status binding differs")
|
|
554
|
+
usage = row["usage"]
|
|
555
|
+
for name in ("forward_attempts", "forward_responses", "input_token_positions", "nonfinite_native_metrics", "optimizer_steps"):
|
|
556
|
+
if type(usage.get(name)) is not int or usage[name] < 0:
|
|
557
|
+
raise ValueError("rank usage is not a measured nonnegative integer")
|
|
558
|
+
records[str(rank)] = row
|
|
559
|
+
except (KeyError, TypeError, ValueError) as exc:
|
|
560
|
+
errors.append({"rank": rank, "error": str(exc)})
|
|
561
|
+
counters["rank_receipts"] = records
|
|
562
|
+
counters["rank_parse_errors"] = errors
|
|
563
|
+
counters["rank_usage_complete"] = len(records) == world_size
|
|
564
|
+
if counters["rank_usage_complete"]:
|
|
565
|
+
usages = [row["usage"] for row in records.values()]
|
|
566
|
+
for key in ("forward_attempts", "forward_responses", "input_token_positions", "nonfinite_native_metrics"):
|
|
567
|
+
counters[key] = sum(row[key] for row in usages)
|
|
568
|
+
steps = {row["optimizer_steps"] for row in usages}
|
|
569
|
+
counters["optimizer_steps"] = min(steps)
|
|
570
|
+
counters["distributed_optimizer_step_agreement"] = len(steps) == 1
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
def run_native_policy_rank(output_root, plan_sha256):
|
|
574
|
+
"""Distributed worker body; invoked once per rank by native torchrun."""
|
|
575
|
+
root = Path(output_root).resolve()
|
|
576
|
+
path = _file(root / "fit-plan.json", "policy launch plan")
|
|
577
|
+
if _sha(path) != plan_sha256:
|
|
578
|
+
raise ValidationError("SmartSearch distributed policy plan identity differs")
|
|
579
|
+
plan = json.loads(path.read_text())
|
|
580
|
+
if _sha(Path(__file__)) != plan.get("toolkit_policy_sha256") or _sha(
|
|
581
|
+
Path(__file__).with_name("smartsearch_policy_worker.py")
|
|
582
|
+
) != plan.get("toolkit_worker_sha256"):
|
|
583
|
+
raise ValidationError("SmartSearch child toolkit bytes differ from the launcher")
|
|
584
|
+
controls = SmartSearchPolicyFitControls(**plan["controls"])
|
|
585
|
+
merge = plan.get("operation") == "merge"
|
|
586
|
+
rank = 0 if merge else int(os.environ.get("RANK", "-1"))
|
|
587
|
+
if not merge and (not 0 <= rank < controls.gpu_processes or int(os.environ.get("WORLD_SIZE", "0")) != controls.gpu_processes):
|
|
588
|
+
raise ValidationError("SmartSearch policy rank must be launched by the bound distributed runtime")
|
|
589
|
+
rank_root = root / f"rank-{rank}-workspace"
|
|
590
|
+
rank_root.mkdir(exist_ok=False)
|
|
591
|
+
counters = {"forward_attempts": 0, "forward_responses": 0, "input_token_positions": 0,
|
|
592
|
+
"forward_observation_scope": "primary_policy_after_on_train_begin",
|
|
593
|
+
"unobserved_reference_forward_calls": None,
|
|
594
|
+
"optimizer_steps": 0, "planned_optimizer_steps": None, "native_logs": [],
|
|
595
|
+
"nonfinite_native_metrics": 0}
|
|
596
|
+
started = time.monotonic()
|
|
597
|
+
try:
|
|
598
|
+
source = Path(plan["source"]["root"])
|
|
599
|
+
for relative, digest in plan["source"]["policy_configs"].items():
|
|
600
|
+
if _sha(_file(source / relative, "native worker source")) != digest:
|
|
601
|
+
raise ExternalDependencyError("SmartSearch distributed native source/config changed")
|
|
602
|
+
with _LOCK, _environment(rank_root, controls.seed), (root / f"native-rank-{rank}.log").open("x") as log, redirect_stdout(log), redirect_stderr(log):
|
|
603
|
+
trainer = _source_import(source, plan.get("native_data_source"))
|
|
604
|
+
if merge:
|
|
605
|
+
trainer.export_model(args=plan["native_config"])
|
|
606
|
+
else:
|
|
607
|
+
trainer.run_exp(args=plan["native_config"], callbacks=[_observer(counters, controls.max_optimizer_steps)])
|
|
608
|
+
_save(root, f"rank-{rank}-terminal.json", {"status": "completed", "rank": rank,
|
|
609
|
+
"plan_sha256": plan_sha256, "usage": counters,
|
|
610
|
+
"elapsed_seconds": time.monotonic() - started})
|
|
611
|
+
except Exception as exc:
|
|
612
|
+
_save(root, f"rank-{rank}-terminal.json", {"status": "failed", "rank": rank,
|
|
613
|
+
"plan_sha256": plan_sha256, "usage": counters,
|
|
614
|
+
"error_type": type(exc).__name__, "error": str(exc),
|
|
615
|
+
"elapsed_seconds": time.monotonic() - started})
|
|
616
|
+
raise
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""Fresh-process, distributed native SmartSearch policy-stage entrypoint."""
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from .smartsearch_policy import run_native_policy_rank
|
|
5
|
+
|
|
6
|
+
if __name__ == "__main__":
|
|
7
|
+
if len(sys.argv) != 3:
|
|
8
|
+
raise SystemExit("expected a create-only policy output root and pinned plan SHA-256")
|
|
9
|
+
run_native_policy_rank(sys.argv[1], sys.argv[2])
|