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,822 @@
|
|
|
1
|
+
"""Pinned Adaptive-RAG silver-label reconstruction and native router training.
|
|
2
|
+
|
|
3
|
+
The author script owns tokenization, seq2seq loss, AdamW/Accelerate updates and
|
|
4
|
+
first-decoder-step A/B/C validation. Run each fit in a dedicated process. No
|
|
5
|
+
alternate classifier loss, generated labels, automatic fit retry or test tuning.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import importlib.metadata
|
|
11
|
+
import importlib.util
|
|
12
|
+
import json
|
|
13
|
+
import math
|
|
14
|
+
import os
|
|
15
|
+
import runpy
|
|
16
|
+
import sys
|
|
17
|
+
import time
|
|
18
|
+
from collections import Counter
|
|
19
|
+
from collections.abc import Mapping
|
|
20
|
+
from contextlib import contextmanager, redirect_stderr, redirect_stdout
|
|
21
|
+
from dataclasses import asdict, dataclass
|
|
22
|
+
from functools import wraps
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
|
|
25
|
+
from agentinputlab.artifacts import load_pinned_json_mapping
|
|
26
|
+
from agentinputlab.contracts import ExternalDependencyError, ValidationError
|
|
27
|
+
from agentinputlab.contracts.serialization import content_hash
|
|
28
|
+
|
|
29
|
+
from .recomp_abstractive import validate_recomp_nltk_assets
|
|
30
|
+
from .recomp_extractive import _LOCK, _save, _scope
|
|
31
|
+
|
|
32
|
+
RELEASE = "acquire.adaptive_rag.rebuilt_offline"
|
|
33
|
+
PROTOCOL = "agentinputlab.adaptive-rag.native_router_fit.v1"
|
|
34
|
+
SCRIPT = "classifier/run_classifier.py"
|
|
35
|
+
_DEPENDENCIES = {
|
|
36
|
+
"transformers": "4.28.1",
|
|
37
|
+
"tokenizers": "0.13.3",
|
|
38
|
+
"accelerate": "0.15.0",
|
|
39
|
+
"numpy": "1.26.4",
|
|
40
|
+
"datasets": "2.14.7",
|
|
41
|
+
"pyarrow": "14.0.2",
|
|
42
|
+
"fsspec": "2023.10.0",
|
|
43
|
+
"huggingface-hub": "0.19.4",
|
|
44
|
+
"nltk": "3.9.2",
|
|
45
|
+
"safetensors": "0.5.3",
|
|
46
|
+
"sentencepiece": "0.2.1",
|
|
47
|
+
"jsonlines": "4.0.0",
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _sha(path):
|
|
52
|
+
from workers.adaptive_rag.driver import _file_sha256
|
|
53
|
+
|
|
54
|
+
return _file_sha256(path)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _regular(path, label):
|
|
58
|
+
supplied = Path(path).expanduser()
|
|
59
|
+
if supplied.is_symlink() or not supplied.is_file():
|
|
60
|
+
raise ValidationError(f"Adaptive-RAG {label} requires a regular non-symlink file")
|
|
61
|
+
return supplied.resolve()
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _new_output_root(output_root, *protected):
|
|
65
|
+
root = Path(output_root).expanduser().absolute()
|
|
66
|
+
if root.exists() or root.is_symlink():
|
|
67
|
+
raise ValidationError("Adaptive-RAG output must be create-only; no automatic retry")
|
|
68
|
+
if any(root.resolve().is_relative_to(Path(p).resolve()) for p in protected):
|
|
69
|
+
raise ValidationError("Adaptive-RAG output must not mutate source or initial assets")
|
|
70
|
+
root.mkdir(parents=True)
|
|
71
|
+
return root
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def validate_adaptive_training_checkout(checkout):
|
|
75
|
+
from workers.adaptive_rag.driver import (
|
|
76
|
+
DEFAULT_MANIFEST,
|
|
77
|
+
CompatibilityPolicy,
|
|
78
|
+
_git,
|
|
79
|
+
_safe_file,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
root = Path(checkout).expanduser()
|
|
83
|
+
if root.is_symlink() or not root.is_dir():
|
|
84
|
+
raise ValidationError("Adaptive-RAG requires a regular native source checkout")
|
|
85
|
+
root = root.resolve()
|
|
86
|
+
policy = CompatibilityPolicy.from_mapping(json.loads(DEFAULT_MANIFEST.read_text()))
|
|
87
|
+
if (
|
|
88
|
+
_git(root, "rev-parse", "HEAD") != policy.commit
|
|
89
|
+
or _git(root, "rev-parse", "HEAD^{tree}") != policy.tree
|
|
90
|
+
or _git(root, "status", "--porcelain=v1", "--untracked-files=all")
|
|
91
|
+
):
|
|
92
|
+
raise ExternalDependencyError("Adaptive-RAG training source must be exact and clean")
|
|
93
|
+
sources = {**policy.source_hashes, policy.license_path: policy.license_sha256}
|
|
94
|
+
# Preprocessing is also executed, not just copied as a provenance label.
|
|
95
|
+
relative = "classifier/preprocess/preprocess_utils.py"
|
|
96
|
+
import hashlib
|
|
97
|
+
|
|
98
|
+
raw = _safe_file(root, relative).read_bytes()
|
|
99
|
+
blob = hashlib.sha1(b"blob " + str(len(raw)).encode() + b"\0" + raw).hexdigest()
|
|
100
|
+
if blob != _git(root, "rev-parse", policy.commit + ":" + relative):
|
|
101
|
+
raise ExternalDependencyError("Adaptive-RAG native label source differs")
|
|
102
|
+
sources[relative] = hashlib.sha256(raw).hexdigest()
|
|
103
|
+
for relative, digest in sources.items():
|
|
104
|
+
if _sha(_safe_file(root, relative)) != digest:
|
|
105
|
+
raise ExternalDependencyError("Adaptive-RAG pinned source hash differs")
|
|
106
|
+
return root, dict(commit=policy.commit, tree=policy.tree, source_files=sources)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def rebuild_adaptive_silver(
|
|
110
|
+
*,
|
|
111
|
+
checkout,
|
|
112
|
+
original_file,
|
|
113
|
+
zero_file,
|
|
114
|
+
single_file,
|
|
115
|
+
multi_file,
|
|
116
|
+
dataset_name,
|
|
117
|
+
teacher_revision,
|
|
118
|
+
output_root,
|
|
119
|
+
max_data_bytes=32 * 1024 * 1024,
|
|
120
|
+
source_and_asset_acknowledged=False,
|
|
121
|
+
):
|
|
122
|
+
"""Call native label_complexity on caller-mounted original/prediction files.
|
|
123
|
+
|
|
124
|
+
The mappings must be native correct-prediction ID sets from the declared
|
|
125
|
+
teacher. This function does not run a teacher or assert teacher/reader parity.
|
|
126
|
+
Native C then B then A overwrites yield A > B > C; unanswerable IDs excluded.
|
|
127
|
+
"""
|
|
128
|
+
if source_and_asset_acknowledged is not True:
|
|
129
|
+
raise ValidationError("Adaptive-RAG label rebuild requires acknowledgement")
|
|
130
|
+
for value in (dataset_name, teacher_revision):
|
|
131
|
+
if not isinstance(value, str) or not value.strip() or "\x00" in value:
|
|
132
|
+
raise ValidationError("Adaptive-RAG dataset and teacher revision must be explicit")
|
|
133
|
+
if type(max_data_bytes) is not int or max_data_bytes < 1:
|
|
134
|
+
raise ValidationError("Adaptive-RAG data byte cap must be positive")
|
|
135
|
+
source, binding = validate_adaptive_training_checkout(checkout)
|
|
136
|
+
paths = {
|
|
137
|
+
name: _regular(path, name)
|
|
138
|
+
for name, path in (
|
|
139
|
+
("original", original_file),
|
|
140
|
+
("zero", zero_file),
|
|
141
|
+
("single", single_file),
|
|
142
|
+
("multi", multi_file),
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
if any(p.stat().st_size > max_data_bytes for p in paths.values()):
|
|
146
|
+
raise ValidationError("Adaptive-RAG label inputs exceed the declared byte cap")
|
|
147
|
+
before = {name: _sha(path) for name, path in paths.items()}
|
|
148
|
+
root = _new_output_root(output_root, source)
|
|
149
|
+
spec = importlib.util.spec_from_file_location(
|
|
150
|
+
"_agentinputlab_pinned_adaptive_labels",
|
|
151
|
+
source / "classifier/preprocess/preprocess_utils.py",
|
|
152
|
+
)
|
|
153
|
+
module = importlib.util.module_from_spec(spec)
|
|
154
|
+
spec.loader.exec_module(module)
|
|
155
|
+
rows = module.label_complexity(
|
|
156
|
+
*(str(paths[n]) for n in ("original", "zero", "single", "multi")), dataset_name
|
|
157
|
+
)
|
|
158
|
+
if before != {name: _sha(path) for name, path in paths.items()}:
|
|
159
|
+
raise ValidationError("Adaptive-RAG label source inputs changed during reconstruction")
|
|
160
|
+
_save(root / "silver.json", rows)
|
|
161
|
+
_save(
|
|
162
|
+
root / "provenance.json",
|
|
163
|
+
dict(
|
|
164
|
+
source=binding,
|
|
165
|
+
native_function="label_complexity",
|
|
166
|
+
dataset=dataset_name,
|
|
167
|
+
teacher_revision=teacher_revision,
|
|
168
|
+
input_files={name: dict(path=str(p), sha256=before[name]) for name, p in paths.items()},
|
|
169
|
+
silver_sha256=_sha(root / "silver.json"),
|
|
170
|
+
rows=len(rows),
|
|
171
|
+
class_counts=dict(Counter(r["answer"] for r in rows)),
|
|
172
|
+
priority=["A", "B", "C"],
|
|
173
|
+
unanswerable_ids_excluded_by_native_source=True,
|
|
174
|
+
new_teacher_calls=0,
|
|
175
|
+
original_reader_matched_teacher_claimed=False,
|
|
176
|
+
),
|
|
177
|
+
)
|
|
178
|
+
return root / "silver.json"
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
@dataclass(frozen=True, slots=True)
|
|
182
|
+
class AdaptiveRAGFitControls:
|
|
183
|
+
epochs: int = 2
|
|
184
|
+
batch_size: int = 8
|
|
185
|
+
eval_batch_size: int = 8
|
|
186
|
+
gradient_accumulation_steps: int = 1
|
|
187
|
+
learning_rate: float = 5e-5
|
|
188
|
+
weight_decay: float = 0.0
|
|
189
|
+
max_seq_length: int = 384
|
|
190
|
+
doc_stride: int = 128
|
|
191
|
+
max_answer_length: int = 30
|
|
192
|
+
max_steps: int | None = None
|
|
193
|
+
max_optimizer_steps: int = 10000
|
|
194
|
+
max_data_bytes: int = 64 * 1024 * 1024
|
|
195
|
+
seed: int = 17
|
|
196
|
+
device: str = "cpu"
|
|
197
|
+
|
|
198
|
+
def __post_init__(self):
|
|
199
|
+
for name in (
|
|
200
|
+
"epochs",
|
|
201
|
+
"batch_size",
|
|
202
|
+
"eval_batch_size",
|
|
203
|
+
"gradient_accumulation_steps",
|
|
204
|
+
"max_seq_length",
|
|
205
|
+
"doc_stride",
|
|
206
|
+
"max_answer_length",
|
|
207
|
+
"max_optimizer_steps",
|
|
208
|
+
"max_data_bytes",
|
|
209
|
+
"seed",
|
|
210
|
+
):
|
|
211
|
+
value = getattr(self, name)
|
|
212
|
+
if type(value) is not int or value < (0 if name == "seed" else 1):
|
|
213
|
+
raise ValidationError(f"Adaptive-RAG {name} must be an integer in range")
|
|
214
|
+
for name in ("learning_rate", "weight_decay"):
|
|
215
|
+
value = getattr(self, name)
|
|
216
|
+
if (
|
|
217
|
+
type(value) not in (int, float)
|
|
218
|
+
or not math.isfinite(value)
|
|
219
|
+
or value < 0
|
|
220
|
+
or (name == "learning_rate" and value == 0)
|
|
221
|
+
):
|
|
222
|
+
raise ValidationError(f"Adaptive-RAG {name} is invalid")
|
|
223
|
+
if self.max_steps is not None and (type(self.max_steps) is not int or self.max_steps < 1):
|
|
224
|
+
raise ValidationError("Adaptive-RAG max_steps must be a positive explicit bound")
|
|
225
|
+
if (
|
|
226
|
+
self.doc_stride >= self.max_seq_length
|
|
227
|
+
or self.max_answer_length > 512
|
|
228
|
+
or self.device not in {"cpu", "cuda"}
|
|
229
|
+
):
|
|
230
|
+
raise ValidationError("Adaptive-RAG sequence, output cap or device is invalid")
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def audit_adaptive_training_data(train_file, dev_file, controls):
|
|
234
|
+
paths = {n: _regular(p, n) for n, p in (("train", train_file), ("dev", dev_file))}
|
|
235
|
+
if paths["train"] == paths["dev"]:
|
|
236
|
+
raise ValidationError("Adaptive-RAG train/dev files must differ")
|
|
237
|
+
evidence, questions, ids = {}, {}, {}
|
|
238
|
+
for split, path in paths.items():
|
|
239
|
+
if path.suffix != ".json" or path.stat().st_size > controls.max_data_bytes:
|
|
240
|
+
raise ValidationError("Adaptive-RAG native JSON data exceeds its declared byte cap")
|
|
241
|
+
try:
|
|
242
|
+
rows = json.loads(path.read_text())
|
|
243
|
+
except (ValueError, UnicodeError) as exc:
|
|
244
|
+
raise ValidationError("Adaptive-RAG data must be native JSON record arrays") from exc
|
|
245
|
+
if not isinstance(rows, list) or not rows:
|
|
246
|
+
raise ValidationError("Adaptive-RAG requires nonempty native records")
|
|
247
|
+
for row in rows:
|
|
248
|
+
if (
|
|
249
|
+
not isinstance(row, dict)
|
|
250
|
+
or any(
|
|
251
|
+
not isinstance(row.get(k), str) or not row[k].strip() or "\x00" in row[k]
|
|
252
|
+
for k in ("id", "question", "dataset_name", "answer")
|
|
253
|
+
)
|
|
254
|
+
or row["answer"] not in {"A", "B", "C"}
|
|
255
|
+
):
|
|
256
|
+
raise ValidationError(
|
|
257
|
+
"Adaptive-RAG native records require id/question/dataset/A-B-C"
|
|
258
|
+
)
|
|
259
|
+
questions[split] = {" ".join(r["question"].casefold().split()) for r in rows}
|
|
260
|
+
ids[split] = {r["id"] for r in rows}
|
|
261
|
+
if len(ids[split]) != len(rows):
|
|
262
|
+
raise ValidationError("Adaptive-RAG native IDs must be unique within each split")
|
|
263
|
+
evidence[split] = dict(
|
|
264
|
+
path=str(path),
|
|
265
|
+
sha256=_sha(path),
|
|
266
|
+
rows=len(rows),
|
|
267
|
+
class_counts=dict(Counter(r["answer"] for r in rows)),
|
|
268
|
+
)
|
|
269
|
+
if questions["train"] & questions["dev"] or ids["train"] & ids["dev"]:
|
|
270
|
+
raise ValidationError("Adaptive-RAG train/dev query or ID overlap is not permitted")
|
|
271
|
+
steps = controls.max_steps or controls.epochs * math.ceil(
|
|
272
|
+
math.ceil(evidence["train"]["rows"] / controls.batch_size)
|
|
273
|
+
/ controls.gradient_accumulation_steps
|
|
274
|
+
)
|
|
275
|
+
if steps > controls.max_optimizer_steps:
|
|
276
|
+
raise ValidationError("Adaptive-RAG optimizer plan exceeds its declared step cap")
|
|
277
|
+
return dict(
|
|
278
|
+
files=evidence,
|
|
279
|
+
minimum_planned_optimizer_steps=steps,
|
|
280
|
+
query_and_id_overlap=False,
|
|
281
|
+
overflow_aware_step_cap_checked_before_native_training=True,
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
def validate_adaptive_router_checkpoint(root, manifest, expected_sha256):
|
|
286
|
+
metadata = load_pinned_json_mapping(manifest, expected_sha256=expected_sha256)
|
|
287
|
+
folder = Path(root).expanduser()
|
|
288
|
+
if folder.is_symlink() or not folder.is_dir():
|
|
289
|
+
raise ValidationError("Adaptive-RAG router checkpoint requires a regular directory")
|
|
290
|
+
folder = folder.resolve()
|
|
291
|
+
files = metadata.get("files")
|
|
292
|
+
if (
|
|
293
|
+
metadata.get("schema") != "agentinputlab.adaptive-rag.router_checkpoint.v1"
|
|
294
|
+
or not isinstance(files, dict)
|
|
295
|
+
or not {"config.json", "model.safetensors", "tokenizer.json"} <= files.keys()
|
|
296
|
+
):
|
|
297
|
+
raise ValidationError(
|
|
298
|
+
"Adaptive-RAG requires an explicit safe T5/tokenizer checkpoint closure"
|
|
299
|
+
)
|
|
300
|
+
if {p.name for p in folder.iterdir()} != set(files):
|
|
301
|
+
raise ValidationError("Adaptive-RAG checkpoint closure contains missing or extra files")
|
|
302
|
+
for name, expected in files.items():
|
|
303
|
+
if (
|
|
304
|
+
not isinstance(name, str)
|
|
305
|
+
or Path(name).name != name
|
|
306
|
+
or name in {".", ".."}
|
|
307
|
+
or name.endswith((".bin", ".pkl", ".pickle", ".py"))
|
|
308
|
+
):
|
|
309
|
+
raise ValidationError("Adaptive-RAG checkpoint paths must be flat and safe")
|
|
310
|
+
if _sha(_regular(folder / name, "checkpoint")) != expected:
|
|
311
|
+
raise ValidationError("Adaptive-RAG checkpoint file hash differs")
|
|
312
|
+
config = json.loads((folder / "config.json").read_text())
|
|
313
|
+
tokenizer_config = folder / "tokenizer_config.json"
|
|
314
|
+
custom_tokenizer = tokenizer_config.exists() and json.loads(tokenizer_config.read_text()).get(
|
|
315
|
+
"auto_map"
|
|
316
|
+
)
|
|
317
|
+
if config.get("model_type") != "t5" or config.get("auto_map") or custom_tokenizer:
|
|
318
|
+
raise ValidationError("Adaptive-RAG native initialization requires local standard T5")
|
|
319
|
+
return folder, metadata
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
def _t5_tied_aliases(tie_word_embeddings):
|
|
323
|
+
aliases = {
|
|
324
|
+
"encoder.embed_tokens.weight": "shared.weight",
|
|
325
|
+
"decoder.embed_tokens.weight": "shared.weight",
|
|
326
|
+
}
|
|
327
|
+
if tie_word_embeddings:
|
|
328
|
+
aliases["lm_head.weight"] = "shared.weight"
|
|
329
|
+
return aliases
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def _align_t5_initial_keys(initial, expected_keys, *, tie_word_embeddings):
|
|
333
|
+
"""Expand only standard T5 tied aliases omitted by safe serialization."""
|
|
334
|
+
expected = set(expected_keys)
|
|
335
|
+
missing = expected - set(initial)
|
|
336
|
+
allowed = _t5_tied_aliases(tie_word_embeddings)
|
|
337
|
+
if set(initial) - expected or missing - set(allowed) or "shared.weight" not in initial:
|
|
338
|
+
raise ValidationError("Adaptive-RAG trained namespace differs from initialization")
|
|
339
|
+
expanded = dict(initial)
|
|
340
|
+
for alias in missing:
|
|
341
|
+
expanded[alias] = initial[allowed[alias]]
|
|
342
|
+
return expanded, {alias: allowed[alias] for alias in sorted(missing)}
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
@contextmanager
|
|
346
|
+
def _observe_native(observed, controls):
|
|
347
|
+
import torch
|
|
348
|
+
import transformers
|
|
349
|
+
from accelerate import Accelerator
|
|
350
|
+
from torch.utils.data import DataLoader, RandomSampler
|
|
351
|
+
|
|
352
|
+
prepare, step = Accelerator.prepare, torch.optim.AdamW.step
|
|
353
|
+
generate = transformers.PreTrainedModel.generate
|
|
354
|
+
restores = []
|
|
355
|
+
|
|
356
|
+
def preparing(accelerator, *objects, **kwargs):
|
|
357
|
+
for obj in objects:
|
|
358
|
+
if isinstance(obj, torch.nn.Module):
|
|
359
|
+
if "model" in observed:
|
|
360
|
+
raise ValidationError("Adaptive-RAG native fit prepared more than one model")
|
|
361
|
+
observed["model"] = obj
|
|
362
|
+
forward = obj.forward
|
|
363
|
+
|
|
364
|
+
@wraps(forward)
|
|
365
|
+
def forwarding(*args, _original_forward=forward, **kw):
|
|
366
|
+
result = _original_forward(*args, **kw)
|
|
367
|
+
if result.loss is not None:
|
|
368
|
+
observed["loss_events"].append(
|
|
369
|
+
dict(
|
|
370
|
+
loss=float(result.loss.detach().cpu()),
|
|
371
|
+
gradient_enabled=torch.is_grad_enabled(),
|
|
372
|
+
label_tokens=int((kw["labels"] != -100).sum().item()),
|
|
373
|
+
)
|
|
374
|
+
)
|
|
375
|
+
return result
|
|
376
|
+
|
|
377
|
+
obj.forward = forwarding
|
|
378
|
+
restores.append((obj, forward))
|
|
379
|
+
if isinstance(obj, DataLoader) and isinstance(obj.sampler, RandomSampler):
|
|
380
|
+
updates = math.ceil(len(obj) / controls.gradient_accumulation_steps)
|
|
381
|
+
planned = controls.max_steps or controls.epochs * updates
|
|
382
|
+
if planned > controls.max_optimizer_steps:
|
|
383
|
+
raise ValidationError("Adaptive-RAG overflow-aware optimizer plan exceeds cap")
|
|
384
|
+
observed["planned_optimizer_steps"] = planned
|
|
385
|
+
observed["native_training_batches"] = len(obj)
|
|
386
|
+
return prepare(accelerator, *objects, **kwargs)
|
|
387
|
+
|
|
388
|
+
def stepping(optimizer, *args, **kwargs):
|
|
389
|
+
result = step(optimizer, *args, **kwargs)
|
|
390
|
+
observed["optimizer_steps"] += 1
|
|
391
|
+
return result
|
|
392
|
+
|
|
393
|
+
def generating(model, *args, **kwargs):
|
|
394
|
+
result = generate(model, *args, **kwargs)
|
|
395
|
+
tokens = result.sequences[:, 1:]
|
|
396
|
+
observed["validation_generation_events"].append(
|
|
397
|
+
dict(
|
|
398
|
+
examples=int(tokens.shape[0]),
|
|
399
|
+
generated_sequence_slots=int(tokens.numel()),
|
|
400
|
+
returned_nonpadding_tokens=int((tokens != model.config.pad_token_id).sum().item()),
|
|
401
|
+
max_length=kwargs.get("max_length"),
|
|
402
|
+
)
|
|
403
|
+
)
|
|
404
|
+
return result
|
|
405
|
+
|
|
406
|
+
Accelerator.prepare, torch.optim.AdamW.step = preparing, stepping
|
|
407
|
+
transformers.PreTrainedModel.generate = generating
|
|
408
|
+
try:
|
|
409
|
+
yield
|
|
410
|
+
finally:
|
|
411
|
+
for model, forward in restores:
|
|
412
|
+
model.forward = forward
|
|
413
|
+
Accelerator.prepare, torch.optim.AdamW.step = prepare, step
|
|
414
|
+
transformers.PreTrainedModel.generate = generate
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
@dataclass(frozen=True, slots=True)
|
|
418
|
+
class AdaptiveRAGTrainedRouterArtifact:
|
|
419
|
+
root: Path
|
|
420
|
+
artifact_id: str
|
|
421
|
+
checkpoint_manifest_sha256: str
|
|
422
|
+
|
|
423
|
+
@property
|
|
424
|
+
def checkpoint(self):
|
|
425
|
+
return self.root / "checkpoint"
|
|
426
|
+
|
|
427
|
+
@classmethod
|
|
428
|
+
def load(cls, root):
|
|
429
|
+
folder = Path(root).expanduser()
|
|
430
|
+
if folder.is_symlink() or not folder.is_dir():
|
|
431
|
+
raise ValidationError("Adaptive-RAG fit artifact directory is invalid")
|
|
432
|
+
folder = folder.resolve()
|
|
433
|
+
metadata = json.loads(_regular(folder / "artifact.json", "artifact").read_text())
|
|
434
|
+
identity = metadata.pop("artifact_id", None)
|
|
435
|
+
if (
|
|
436
|
+
identity != content_hash(metadata)
|
|
437
|
+
or metadata.get("protocol") != PROTOCOL
|
|
438
|
+
or metadata.get("release_id") != RELEASE
|
|
439
|
+
):
|
|
440
|
+
raise ValidationError("Adaptive-RAG fit artifact identity differs")
|
|
441
|
+
for name in ("fit-plan.json", "fit-terminal.json"):
|
|
442
|
+
if _sha(_regular(folder / name, name)) != metadata.get(name + "_sha256"):
|
|
443
|
+
raise ValidationError("Adaptive-RAG fit plan/terminal hash differs")
|
|
444
|
+
terminal = json.loads((folder / "fit-terminal.json").read_text())
|
|
445
|
+
if (
|
|
446
|
+
terminal.get("status") != "trained_candidate"
|
|
447
|
+
or terminal.get("optimizer_steps", 0) < 1
|
|
448
|
+
or terminal.get("changed_parameter_tensors", 0) < 1
|
|
449
|
+
or not terminal.get("validation_generation_events")
|
|
450
|
+
):
|
|
451
|
+
raise ValidationError("Adaptive-RAG native fit/validation is incomplete")
|
|
452
|
+
native_files = metadata.get("native_files")
|
|
453
|
+
if (
|
|
454
|
+
not isinstance(native_files, dict)
|
|
455
|
+
or not {
|
|
456
|
+
"pytorch_model.bin",
|
|
457
|
+
"dict_id_pred_results.json",
|
|
458
|
+
"final_eval_results.json",
|
|
459
|
+
"final_eval_results_perClass.json",
|
|
460
|
+
}
|
|
461
|
+
<= native_files.keys()
|
|
462
|
+
):
|
|
463
|
+
raise ValidationError("Adaptive-RAG native output closure is incomplete")
|
|
464
|
+
if (folder / "native").is_symlink() or any(
|
|
465
|
+
p.is_symlink() for p in (folder / "native").rglob("*")
|
|
466
|
+
):
|
|
467
|
+
raise ValidationError("Adaptive-RAG native output closure must not contain symlinks")
|
|
468
|
+
actual_files = {
|
|
469
|
+
p.relative_to(folder / "native").as_posix()
|
|
470
|
+
for p in (folder / "native").rglob("*")
|
|
471
|
+
if p.is_file()
|
|
472
|
+
}
|
|
473
|
+
if actual_files != set(native_files):
|
|
474
|
+
raise ValidationError(
|
|
475
|
+
"Adaptive-RAG native output closure contains extra or missing files"
|
|
476
|
+
)
|
|
477
|
+
for relative, expected in native_files.items():
|
|
478
|
+
p = Path(relative)
|
|
479
|
+
if p.is_absolute() or ".." in p.parts or str(p) != relative:
|
|
480
|
+
raise ValidationError("Adaptive-RAG native closure path is invalid")
|
|
481
|
+
if _sha(_regular(folder / "native" / p, "native output")) != expected:
|
|
482
|
+
raise ValidationError("Adaptive-RAG native output closure differs")
|
|
483
|
+
digest = metadata["checkpoint_manifest_sha256"]
|
|
484
|
+
validate_adaptive_router_checkpoint(
|
|
485
|
+
folder / "checkpoint", folder / "checkpoint-manifest.json", digest
|
|
486
|
+
)
|
|
487
|
+
return cls(folder, identity, digest)
|
|
488
|
+
|
|
489
|
+
def router_bindings(self):
|
|
490
|
+
"""Bind the new snapshot to the existing controlled router deployment.
|
|
491
|
+
|
|
492
|
+
Generator/retriever/corpus/index identities remain independently required.
|
|
493
|
+
This does not promote controlled retrieval arms to upstream score parity.
|
|
494
|
+
"""
|
|
495
|
+
from workers.adaptive_rag.driver import _path_closure_sha256
|
|
496
|
+
|
|
497
|
+
current = self.load(self.root)
|
|
498
|
+
return dict(
|
|
499
|
+
router_revision="native-fit-" + current.artifact_id,
|
|
500
|
+
router_snapshot_sha256=_path_closure_sha256(current.checkpoint),
|
|
501
|
+
router_weights_sha256=_sha(current.checkpoint / "model.safetensors"),
|
|
502
|
+
router_tokenizer_sha256=_sha(current.checkpoint / "tokenizer.json"),
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
def router_configuration(self):
|
|
506
|
+
"""Keep native fit/validation input truncation explicit at deployment."""
|
|
507
|
+
current = self.load(self.root)
|
|
508
|
+
plan = json.loads((current.root / "fit-plan.json").read_text())
|
|
509
|
+
return dict(max_input_tokens=plan["controls"]["max_seq_length"])
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
class AdaptiveRAGOfflineTraining:
|
|
513
|
+
release_id = RELEASE
|
|
514
|
+
|
|
515
|
+
def __init__(self, controls=None):
|
|
516
|
+
self.controls = (
|
|
517
|
+
AdaptiveRAGFitControls(**controls)
|
|
518
|
+
if isinstance(controls, Mapping)
|
|
519
|
+
else controls or AdaptiveRAGFitControls()
|
|
520
|
+
)
|
|
521
|
+
if not isinstance(self.controls, AdaptiveRAGFitControls):
|
|
522
|
+
raise ValidationError("Adaptive-RAG fit requires typed controls")
|
|
523
|
+
|
|
524
|
+
def fit(
|
|
525
|
+
self,
|
|
526
|
+
*,
|
|
527
|
+
checkout,
|
|
528
|
+
initial_checkpoint,
|
|
529
|
+
initial_checkpoint_manifest,
|
|
530
|
+
initial_manifest_sha256,
|
|
531
|
+
train_file,
|
|
532
|
+
dev_file,
|
|
533
|
+
data_provenance,
|
|
534
|
+
data_provenance_sha256,
|
|
535
|
+
nltk_root,
|
|
536
|
+
nltk_manifest,
|
|
537
|
+
nltk_manifest_sha256,
|
|
538
|
+
output_root,
|
|
539
|
+
source_and_asset_acknowledged=False,
|
|
540
|
+
):
|
|
541
|
+
if source_and_asset_acknowledged is not True:
|
|
542
|
+
raise ValidationError(
|
|
543
|
+
"Adaptive-RAG fit requires explicit source/model/data acknowledgement"
|
|
544
|
+
)
|
|
545
|
+
source, binding = validate_adaptive_training_checkout(checkout)
|
|
546
|
+
initial, _ = validate_adaptive_router_checkpoint(
|
|
547
|
+
initial_checkpoint, initial_checkpoint_manifest, initial_manifest_sha256
|
|
548
|
+
)
|
|
549
|
+
c = self.controls
|
|
550
|
+
audit = audit_adaptive_training_data(train_file, dev_file, c)
|
|
551
|
+
provenance = load_pinned_json_mapping(
|
|
552
|
+
data_provenance, expected_sha256=data_provenance_sha256
|
|
553
|
+
)
|
|
554
|
+
if (
|
|
555
|
+
provenance.get("schema") != "agentinputlab.adaptive-rag.training_data.v1"
|
|
556
|
+
or not isinstance(provenance.get("teacher_revision"), str)
|
|
557
|
+
or not provenance["teacher_revision"].strip()
|
|
558
|
+
or any(
|
|
559
|
+
provenance.get("files", {}).get(split, {}).get("sha256")
|
|
560
|
+
!= audit["files"][split]["sha256"]
|
|
561
|
+
for split in ("train", "dev")
|
|
562
|
+
)
|
|
563
|
+
):
|
|
564
|
+
raise ValidationError(
|
|
565
|
+
"Adaptive-RAG training provenance must bind both native data files and teacher"
|
|
566
|
+
)
|
|
567
|
+
resources = validate_recomp_nltk_assets(nltk_root, nltk_manifest, nltk_manifest_sha256)
|
|
568
|
+
versions = {name: importlib.metadata.version(name) for name in ("torch", *_DEPENDENCIES)}
|
|
569
|
+
if versions["torch"] not in {"1.13.0", "1.13.0+cpu", "1.13.0+cu117"} or any(
|
|
570
|
+
versions[k] != v for k, v in _DEPENDENCIES.items()
|
|
571
|
+
):
|
|
572
|
+
raise ExternalDependencyError(
|
|
573
|
+
"Adaptive-RAG fit requires documented isolated dependency versions"
|
|
574
|
+
)
|
|
575
|
+
if os.environ.get("WORLD_SIZE", "1") != "1":
|
|
576
|
+
raise ValidationError("Adaptive-RAG bounded fit requires one process")
|
|
577
|
+
import torch
|
|
578
|
+
|
|
579
|
+
if (c.device == "cpu" and torch.cuda.is_available()) or (
|
|
580
|
+
c.device == "cuda" and (not torch.cuda.is_available() or torch.cuda.device_count() != 1)
|
|
581
|
+
):
|
|
582
|
+
raise ValidationError("Select no visible CUDA devices for CPU or exactly one for CUDA")
|
|
583
|
+
from safetensors.torch import load_file
|
|
584
|
+
|
|
585
|
+
initial_tensors = load_file(str(initial / "model.safetensors"), device="cpu")
|
|
586
|
+
tied_words = json.loads((initial / "config.json").read_text()).get(
|
|
587
|
+
"tie_word_embeddings", True
|
|
588
|
+
)
|
|
589
|
+
for alias, canonical in _t5_tied_aliases(tied_words).items():
|
|
590
|
+
if alias in initial_tensors and (
|
|
591
|
+
canonical not in initial_tensors
|
|
592
|
+
or not torch.equal(initial_tensors[alias], initial_tensors[canonical])
|
|
593
|
+
):
|
|
594
|
+
raise ValidationError("Adaptive-RAG initial tied T5 weights disagree")
|
|
595
|
+
root = _new_output_root(output_root, source, initial)
|
|
596
|
+
(root / "native").mkdir()
|
|
597
|
+
command = [
|
|
598
|
+
str(source / SCRIPT),
|
|
599
|
+
"--do_train",
|
|
600
|
+
"--do_eval",
|
|
601
|
+
"--model_name_or_path",
|
|
602
|
+
str(initial),
|
|
603
|
+
"--train_file",
|
|
604
|
+
audit["files"]["train"]["path"],
|
|
605
|
+
"--validation_file",
|
|
606
|
+
audit["files"]["dev"]["path"],
|
|
607
|
+
"--question_column",
|
|
608
|
+
"question",
|
|
609
|
+
"--answer_column",
|
|
610
|
+
"answer",
|
|
611
|
+
"--output_dir",
|
|
612
|
+
str(root / "native"),
|
|
613
|
+
"--num_train_epochs",
|
|
614
|
+
str(c.epochs),
|
|
615
|
+
"--per_device_train_batch_size",
|
|
616
|
+
str(c.batch_size),
|
|
617
|
+
"--per_device_eval_batch_size",
|
|
618
|
+
str(c.eval_batch_size),
|
|
619
|
+
"--gradient_accumulation_steps",
|
|
620
|
+
str(c.gradient_accumulation_steps),
|
|
621
|
+
"--learning_rate",
|
|
622
|
+
str(c.learning_rate),
|
|
623
|
+
"--weight_decay",
|
|
624
|
+
str(c.weight_decay),
|
|
625
|
+
"--max_seq_length",
|
|
626
|
+
str(c.max_seq_length),
|
|
627
|
+
"--doc_stride",
|
|
628
|
+
str(c.doc_stride),
|
|
629
|
+
"--max_answer_length",
|
|
630
|
+
str(c.max_answer_length),
|
|
631
|
+
"--val_max_answer_length",
|
|
632
|
+
str(c.max_answer_length),
|
|
633
|
+
"--seed",
|
|
634
|
+
str(c.seed),
|
|
635
|
+
]
|
|
636
|
+
if c.max_steps is not None:
|
|
637
|
+
command.extend(("--max_train_steps", str(c.max_steps)))
|
|
638
|
+
plan = dict(
|
|
639
|
+
protocol=PROTOCOL,
|
|
640
|
+
release_id=RELEASE,
|
|
641
|
+
controls=asdict(c),
|
|
642
|
+
source=binding,
|
|
643
|
+
split_audit=audit,
|
|
644
|
+
data_provenance=provenance,
|
|
645
|
+
data_provenance_sha256=data_provenance_sha256,
|
|
646
|
+
initial_manifest_sha256=initial_manifest_sha256,
|
|
647
|
+
nltk_manifest_sha256=nltk_manifest_sha256,
|
|
648
|
+
dependency_versions=versions,
|
|
649
|
+
native_argv=command,
|
|
650
|
+
dependency_lock_adaptation_not_original_git_transformers=True,
|
|
651
|
+
original_paper_initialization_or_teacher_parity_claimed=False,
|
|
652
|
+
automatic_retry=False,
|
|
653
|
+
)
|
|
654
|
+
_save(root / "fit-plan.json", plan)
|
|
655
|
+
observed = dict(optimizer_steps=0, loss_events=[], validation_generation_events=[])
|
|
656
|
+
started, cpu = time.monotonic(), time.process_time()
|
|
657
|
+
try:
|
|
658
|
+
with _LOCK, _scope(root, c.seed):
|
|
659
|
+
import nltk
|
|
660
|
+
from safetensors.torch import load_file, save_file
|
|
661
|
+
from transformers import AutoTokenizer
|
|
662
|
+
|
|
663
|
+
paths, modules = sys.path[:], sys.modules.pop("utils", None)
|
|
664
|
+
nltk_paths = nltk.data.path[:]
|
|
665
|
+
environment = {
|
|
666
|
+
k: os.environ.get(k)
|
|
667
|
+
for k in (
|
|
668
|
+
"TRANSFORMERS_CACHE",
|
|
669
|
+
"HF_DATASETS_CACHE",
|
|
670
|
+
"NLTK_DATA",
|
|
671
|
+
"HF_DATASETS_OFFLINE",
|
|
672
|
+
)
|
|
673
|
+
}
|
|
674
|
+
sys.path.insert(0, str(source / "classifier"))
|
|
675
|
+
nltk.data.path.insert(0, str(resources))
|
|
676
|
+
os.environ.update(
|
|
677
|
+
NLTK_DATA=str(resources),
|
|
678
|
+
HF_DATASETS_OFFLINE="1",
|
|
679
|
+
HF_DATASETS_CACHE=str(root / "dataset-cache"),
|
|
680
|
+
)
|
|
681
|
+
sys.argv[:] = command
|
|
682
|
+
try:
|
|
683
|
+
with (
|
|
684
|
+
_observe_native(observed, c),
|
|
685
|
+
(root / "native-training.log").open("x") as log,
|
|
686
|
+
redirect_stdout(log),
|
|
687
|
+
redirect_stderr(log),
|
|
688
|
+
):
|
|
689
|
+
runpy.run_path(str(source / SCRIPT), run_name="__main__")
|
|
690
|
+
finally:
|
|
691
|
+
sys.path[:] = paths
|
|
692
|
+
sys.modules.pop("utils", None)
|
|
693
|
+
if modules is not None:
|
|
694
|
+
sys.modules["utils"] = modules
|
|
695
|
+
nltk.data.path[:] = nltk_paths
|
|
696
|
+
for name, value in environment.items():
|
|
697
|
+
if value is None:
|
|
698
|
+
os.environ.pop(name, None)
|
|
699
|
+
else:
|
|
700
|
+
os.environ[name] = value
|
|
701
|
+
model = observed.pop("model")
|
|
702
|
+
if (
|
|
703
|
+
observed["optimizer_steps"] != observed.get("planned_optimizer_steps")
|
|
704
|
+
or not observed["loss_events"]
|
|
705
|
+
or not all(math.isfinite(e["loss"]) for e in observed["loss_events"])
|
|
706
|
+
):
|
|
707
|
+
raise ValidationError("Adaptive-RAG native optimizer steps or losses differ")
|
|
708
|
+
validation = json.loads((root / "native/dict_id_pred_results.json").read_text())
|
|
709
|
+
dev = json.loads(Path(audit["files"]["dev"]["path"]).read_text())
|
|
710
|
+
if set(validation) != {r["id"] for r in dev} or any(
|
|
711
|
+
validation[r["id"]]["answer"] != r["answer"]
|
|
712
|
+
or validation[r["id"]]["prediction"] not in {"A", "B", "C"}
|
|
713
|
+
for r in dev
|
|
714
|
+
):
|
|
715
|
+
raise ValidationError("Adaptive-RAG native validation records differ")
|
|
716
|
+
accuracy = (
|
|
717
|
+
100
|
|
718
|
+
* sum(validation[r["id"]]["prediction"] == r["answer"] for r in dev)
|
|
719
|
+
/ len(dev)
|
|
720
|
+
)
|
|
721
|
+
native_accuracy = json.loads((root / "native/final_eval_results.json").read_text())[
|
|
722
|
+
"final_acc_score"
|
|
723
|
+
]
|
|
724
|
+
if not math.isclose(accuracy, native_accuracy, rel_tol=1e-12):
|
|
725
|
+
raise ValidationError("Adaptive-RAG native validation accuracy differs")
|
|
726
|
+
live = model.state_dict()
|
|
727
|
+
before, aliases = _align_t5_initial_keys(
|
|
728
|
+
initial_tensors, live, tie_word_embeddings=tied_words
|
|
729
|
+
)
|
|
730
|
+
for alias, canonical in aliases.items():
|
|
731
|
+
if live[alias].data_ptr() != live[canonical].data_ptr():
|
|
732
|
+
raise ValidationError(
|
|
733
|
+
"Adaptive-RAG safe omitted key is not a native tied weight"
|
|
734
|
+
)
|
|
735
|
+
trained = {n: t.detach().cpu().contiguous().clone() for n, t in live.items()}
|
|
736
|
+
changed = sum(not torch.equal(t, before[n]) for n, t in trained.items())
|
|
737
|
+
if not changed:
|
|
738
|
+
raise ValidationError("Adaptive-RAG native fit changed no model tensors")
|
|
739
|
+
destination = root / "checkpoint"
|
|
740
|
+
destination.mkdir()
|
|
741
|
+
model.config.save_pretrained(destination)
|
|
742
|
+
AutoTokenizer.from_pretrained(
|
|
743
|
+
str(initial), local_files_only=True, trust_remote_code=False
|
|
744
|
+
).save_pretrained(destination)
|
|
745
|
+
save_file(
|
|
746
|
+
trained, str(destination / "model.safetensors"), metadata={"format": "pt"}
|
|
747
|
+
)
|
|
748
|
+
files = {p.name: _sha(p) for p in destination.iterdir()}
|
|
749
|
+
_save(
|
|
750
|
+
root / "checkpoint-manifest.json",
|
|
751
|
+
dict(schema="agentinputlab.adaptive-rag.router_checkpoint.v1", files=files),
|
|
752
|
+
)
|
|
753
|
+
digest = _sha(root / "checkpoint-manifest.json")
|
|
754
|
+
validate_adaptive_router_checkpoint(
|
|
755
|
+
destination, root / "checkpoint-manifest.json", digest
|
|
756
|
+
)
|
|
757
|
+
exported = load_file(str(destination / "model.safetensors"), device="cpu")
|
|
758
|
+
if not all(torch.equal(t, exported[n]) for n, t in trained.items()):
|
|
759
|
+
raise ValidationError(
|
|
760
|
+
"Adaptive-RAG safe export differs from live trained states"
|
|
761
|
+
)
|
|
762
|
+
_save(
|
|
763
|
+
root / "fit-terminal.json",
|
|
764
|
+
dict(
|
|
765
|
+
status="trained_candidate",
|
|
766
|
+
**observed,
|
|
767
|
+
changed_parameter_tensors=changed,
|
|
768
|
+
initial_safe_tensor_count=len(initial_tensors),
|
|
769
|
+
exported_tensor_count=len(trained),
|
|
770
|
+
initial_native_tied_aliases_expanded=aliases,
|
|
771
|
+
validation_rows=len(dev),
|
|
772
|
+
native_validation_accuracy=accuracy,
|
|
773
|
+
wall_seconds=time.monotonic() - started,
|
|
774
|
+
cpu_seconds=time.process_time() - cpu,
|
|
775
|
+
training_and_validation_compute_separate_not_free=True,
|
|
776
|
+
GPU_compute_not_fully_metered=True,
|
|
777
|
+
native_generation_costs_included=True,
|
|
778
|
+
original_published_score_parity=False,
|
|
779
|
+
automatic_retry=False,
|
|
780
|
+
),
|
|
781
|
+
)
|
|
782
|
+
metadata = dict(
|
|
783
|
+
protocol=PROTOCOL,
|
|
784
|
+
release_id=RELEASE,
|
|
785
|
+
checkpoint_manifest_sha256=digest,
|
|
786
|
+
**{n + "_sha256": _sha(root / n) for n in ("fit-plan.json", "fit-terminal.json")},
|
|
787
|
+
native_files={
|
|
788
|
+
p.relative_to(root / "native").as_posix(): _sha(p)
|
|
789
|
+
for p in (root / "native").rglob("*")
|
|
790
|
+
if p.is_file()
|
|
791
|
+
},
|
|
792
|
+
full_quality_acceptance=False,
|
|
793
|
+
paper_results_changed=False,
|
|
794
|
+
)
|
|
795
|
+
_save(root / "artifact.json", dict(**metadata, artifact_id=content_hash(metadata)))
|
|
796
|
+
return AdaptiveRAGTrainedRouterArtifact.load(root)
|
|
797
|
+
except Exception as exc:
|
|
798
|
+
observed.pop("model", None)
|
|
799
|
+
if not (root / "fit-terminal.json").exists():
|
|
800
|
+
_save(
|
|
801
|
+
root / "fit-terminal.json",
|
|
802
|
+
dict(
|
|
803
|
+
status="failed_terminal",
|
|
804
|
+
**observed,
|
|
805
|
+
error_type=type(exc).__name__,
|
|
806
|
+
error=str(exc),
|
|
807
|
+
automatic_retry=False,
|
|
808
|
+
wall_seconds=time.monotonic() - started,
|
|
809
|
+
cpu_seconds=time.process_time() - cpu,
|
|
810
|
+
),
|
|
811
|
+
)
|
|
812
|
+
raise
|
|
813
|
+
|
|
814
|
+
|
|
815
|
+
__all__ = [
|
|
816
|
+
"AdaptiveRAGFitControls",
|
|
817
|
+
"AdaptiveRAGOfflineTraining",
|
|
818
|
+
"AdaptiveRAGTrainedRouterArtifact",
|
|
819
|
+
"audit_adaptive_training_data",
|
|
820
|
+
"rebuild_adaptive_silver",
|
|
821
|
+
"validate_adaptive_router_checkpoint",
|
|
822
|
+
]
|