ins-pricing 0.4.5__tar.gz → 0.5.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/PKG-INFO +1 -1
  2. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/README.md +48 -22
  3. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/__init__.py +142 -90
  4. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/cli/BayesOpt_entry.py +58 -46
  5. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/cli/BayesOpt_incremental.py +77 -110
  6. ins_pricing-0.5.1/ins_pricing/cli/Explain_Run.py +44 -0
  7. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/cli/Explain_entry.py +551 -577
  8. ins_pricing-0.5.1/ins_pricing/cli/Pricing_Run.py +44 -0
  9. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/cli/bayesopt_entry_runner.py +51 -16
  10. ins_pricing-0.5.1/ins_pricing/cli/utils/bootstrap.py +23 -0
  11. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/cli/utils/cli_common.py +256 -256
  12. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/cli/utils/cli_config.py +379 -360
  13. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/cli/utils/import_resolver.py +375 -358
  14. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/cli/utils/notebook_utils.py +256 -242
  15. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/cli/watchdog_run.py +216 -198
  16. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/frontend/__init__.py +10 -10
  17. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/frontend/app.py +132 -61
  18. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/frontend/config_builder.py +33 -0
  19. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/frontend/example_config.json +11 -0
  20. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/frontend/example_workflows.py +1 -1
  21. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/frontend/runner.py +340 -388
  22. ins_pricing-0.5.1/ins_pricing/governance/__init__.py +20 -0
  23. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/governance/release.py +159 -159
  24. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/modelling/README.md +1 -1
  25. ins_pricing-0.5.1/ins_pricing/modelling/__init__.py +150 -0
  26. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/README.md +31 -13
  27. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/__init__.py +64 -102
  28. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/config_components.py +12 -0
  29. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/config_preprocess.py +589 -552
  30. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/core.py +987 -958
  31. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/model_explain_mixin.py +296 -296
  32. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/model_plotting_mixin.py +488 -548
  33. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/models/__init__.py +27 -27
  34. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/models/model_ft_components.py +349 -342
  35. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/models/model_ft_trainer.py +921 -913
  36. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/models/model_gnn.py +794 -785
  37. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/models/model_resn.py +454 -446
  38. ins_pricing-0.5.1/ins_pricing/modelling/bayesopt/trainers/__init__.py +19 -0
  39. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/trainers/trainer_base.py +1294 -1282
  40. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/trainers/trainer_ft.py +64 -56
  41. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/trainers/trainer_glm.py +203 -198
  42. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/trainers/trainer_gnn.py +333 -325
  43. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/trainers/trainer_resn.py +279 -267
  44. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/trainers/trainer_xgb.py +515 -313
  45. ins_pricing-0.5.1/ins_pricing/modelling/bayesopt/utils/__init__.py +67 -0
  46. ins_pricing-0.5.1/ins_pricing/modelling/bayesopt/utils/constants.py +21 -0
  47. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/utils/distributed_utils.py +193 -186
  48. ins_pricing-0.5.1/ins_pricing/modelling/bayesopt/utils/io_utils.py +7 -0
  49. ins_pricing-0.5.1/ins_pricing/modelling/bayesopt/utils/losses.py +27 -0
  50. ins_pricing-0.5.1/ins_pricing/modelling/bayesopt/utils/metrics_and_devices.py +17 -0
  51. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/bayesopt/utils/torch_trainer_mixin.py +636 -623
  52. {ins_pricing-0.4.5/ins_pricing/modelling/core → ins_pricing-0.5.1/ins_pricing/modelling}/evaluation.py +113 -104
  53. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/modelling/explain/__init__.py +55 -55
  54. ins_pricing-0.5.1/ins_pricing/modelling/explain/metrics.py +29 -0
  55. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/modelling/explain/permutation.py +237 -237
  56. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/modelling/plotting/__init__.py +40 -36
  57. ins_pricing-0.5.1/ins_pricing/modelling/plotting/compat.py +228 -0
  58. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/modelling/plotting/curves.py +572 -572
  59. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/modelling/plotting/diagnostics.py +163 -163
  60. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/modelling/plotting/geo.py +362 -362
  61. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/modelling/plotting/importance.py +121 -121
  62. ins_pricing-0.5.1/ins_pricing/pricing/__init__.py +27 -0
  63. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/pricing/factors.py +67 -56
  64. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/production/__init__.py +35 -25
  65. ins_pricing-0.4.5/ins_pricing/production/predict.py → ins_pricing-0.5.1/ins_pricing/production/inference.py +140 -57
  66. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/production/monitoring.py +8 -21
  67. ins_pricing-0.5.1/ins_pricing/reporting/__init__.py +11 -0
  68. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/setup.py +1 -1
  69. ins_pricing-0.5.1/ins_pricing/tests/production/test_inference.py +90 -0
  70. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/utils/__init__.py +112 -78
  71. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/utils/device.py +258 -237
  72. ins_pricing-0.5.1/ins_pricing/utils/features.py +53 -0
  73. ins_pricing-0.5.1/ins_pricing/utils/io.py +72 -0
  74. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/utils/logging.py +34 -1
  75. {ins_pricing-0.4.5/ins_pricing/modelling/core/bayesopt → ins_pricing-0.5.1/ins_pricing}/utils/losses.py +125 -129
  76. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/utils/metrics.py +158 -24
  77. ins_pricing-0.5.1/ins_pricing/utils/numerics.py +76 -0
  78. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/utils/paths.py +9 -1
  79. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/utils/profiling.py +8 -4
  80. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing.egg-info/PKG-INFO +1 -1
  81. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing.egg-info/SOURCES.txt +35 -33
  82. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/pyproject.toml +1 -1
  83. ins_pricing-0.4.5/ins_pricing/cli/Explain_Run.py +0 -25
  84. ins_pricing-0.4.5/ins_pricing/cli/Pricing_Run.py +0 -25
  85. ins_pricing-0.4.5/ins_pricing/governance/__init__.py +0 -20
  86. ins_pricing-0.4.5/ins_pricing/modelling/__init__.py +0 -95
  87. ins_pricing-0.4.5/ins_pricing/modelling/core/BayesOpt.py +0 -146
  88. ins_pricing-0.4.5/ins_pricing/modelling/core/__init__.py +0 -1
  89. ins_pricing-0.4.5/ins_pricing/modelling/core/bayesopt/trainers/__init__.py +0 -19
  90. ins_pricing-0.4.5/ins_pricing/modelling/core/bayesopt/utils/__init__.py +0 -86
  91. ins_pricing-0.4.5/ins_pricing/modelling/core/bayesopt/utils/constants.py +0 -183
  92. ins_pricing-0.4.5/ins_pricing/modelling/core/bayesopt/utils/io_utils.py +0 -126
  93. ins_pricing-0.4.5/ins_pricing/modelling/core/bayesopt/utils/metrics_and_devices.py +0 -555
  94. ins_pricing-0.4.5/ins_pricing/modelling/core/bayesopt/utils.py +0 -105
  95. ins_pricing-0.4.5/ins_pricing/modelling/core/bayesopt/utils_backup.py +0 -1503
  96. ins_pricing-0.4.5/ins_pricing/modelling/explain/metrics.py +0 -176
  97. ins_pricing-0.4.5/ins_pricing/pricing/__init__.py +0 -27
  98. ins_pricing-0.4.5/ins_pricing/reporting/__init__.py +0 -11
  99. ins_pricing-0.4.5/ins_pricing/tests/production/test_predict.py +0 -233
  100. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/MANIFEST.in +0 -0
  101. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/README.md +0 -0
  102. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/cli/__init__.py +0 -0
  103. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/cli/utils/__init__.py +0 -0
  104. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/cli/utils/evaluation_context.py +0 -0
  105. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/cli/utils/run_logging.py +0 -0
  106. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/exceptions.py +0 -0
  107. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/frontend/README.md +0 -0
  108. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/frontend/ft_workflow.py +0 -0
  109. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/governance/README.md +0 -0
  110. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/governance/approval.py +0 -0
  111. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/governance/audit.py +0 -0
  112. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/governance/registry.py +0 -0
  113. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/modelling/explain/gradients.py +0 -0
  114. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/modelling/explain/shap_utils.py +0 -0
  115. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/modelling/plotting/common.py +0 -0
  116. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/pricing/README.md +0 -0
  117. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/pricing/calibration.py +0 -0
  118. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/pricing/data_quality.py +0 -0
  119. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/pricing/exposure.py +0 -0
  120. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/pricing/monitoring.py +0 -0
  121. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/pricing/rate_table.py +0 -0
  122. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/production/drift.py +0 -0
  123. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/production/preprocess.py +0 -0
  124. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/production/scoring.py +0 -0
  125. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/reporting/README.md +0 -0
  126. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/reporting/report_builder.py +0 -0
  127. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/reporting/scheduler.py +0 -0
  128. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/governance/__init__.py +0 -0
  129. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/governance/test_audit.py +0 -0
  130. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/governance/test_registry.py +0 -0
  131. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/governance/test_release.py +0 -0
  132. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/modelling/conftest.py +0 -0
  133. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/modelling/test_cross_val_generic.py +0 -0
  134. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/modelling/test_distributed_utils.py +0 -0
  135. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/modelling/test_explain.py +0 -0
  136. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/modelling/test_geo_tokens_split.py +0 -0
  137. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/modelling/test_graph_cache.py +0 -0
  138. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/modelling/test_plotting.py +0 -0
  139. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/modelling/test_plotting_library.py +0 -0
  140. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/modelling/test_preprocessor.py +0 -0
  141. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/pricing/__init__.py +0 -0
  142. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/pricing/test_calibration.py +0 -0
  143. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/pricing/test_exposure.py +0 -0
  144. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/pricing/test_factors.py +0 -0
  145. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/pricing/test_rate_table.py +0 -0
  146. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/production/__init__.py +0 -0
  147. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/production/test_monitoring.py +0 -0
  148. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/production/test_preprocess.py +0 -0
  149. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/tests/production/test_scoring.py +0 -0
  150. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/utils/torch_compat.py +0 -0
  151. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing/utils/validation.py +0 -0
  152. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing.egg-info/dependency_links.txt +0 -0
  153. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing.egg-info/requires.txt +0 -0
  154. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/ins_pricing.egg-info/top_level.txt +0 -0
  155. {ins_pricing-0.4.5 → ins_pricing-0.5.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ins_pricing
3
- Version: 0.4.5
3
+ Version: 0.5.1
4
4
  Summary: Reusable modelling, pricing, governance, and reporting utilities.
5
5
  Author: meishi125478
6
6
  License: Proprietary
@@ -7,12 +7,13 @@ between modelling, production, governance, and reporting.
7
7
 
8
8
  ## Architecture
9
9
 
10
- - `cli/`: CLI entry points and shared utilities.
11
- - `modelling/`
12
- - `core/`: BayesOpt training core (GLM / XGB / ResNet / FT / GNN).
13
- - `plotting/`: model-agnostic curves and geo visualizations.
14
- - `explain/`: permutation, gradients, and SHAP helpers.
15
- - `examples/`: demo configs and notebooks (repo only; not packaged).
10
+ - `cli/`: CLI entry points and shared utilities.
11
+ - `modelling/`
12
+ - `bayesopt/`: BayesOpt training core (GLM / XGB / ResNet / FT / GNN).
13
+ - `plotting/`: model-agnostic curves and geo visualizations.
14
+ - `explain/`: permutation, gradients, and SHAP helpers.
15
+ - `evaluation.py`: calibration, metrics, and evaluation utilities.
16
+ - `examples/`: demo configs and notebooks (repo only; not packaged).
16
17
  - `pricing/`: factor tables, calibration, exposure, monitoring.
17
18
  - `production/`: scoring, metrics, drift/PSI.
18
19
  - `governance/`: registry, approval, audit workflows.
@@ -31,29 +32,54 @@ between modelling, production, governance, and reporting.
31
32
  - `from ins_pricing.explain import permutation_importance, integrated_gradients_torch`
32
33
  4. Pricing loop
33
34
  - `from ins_pricing.pricing import build_factor_table, rate_premium`
34
- 5. Production and governance
35
- - `from ins_pricing.production import batch_score, psi_report`
36
- - `from ins_pricing.governance import ModelRegistry, ReleaseManager`
35
+ 5. Production and governance
36
+ - `from ins_pricing.production import batch_score, psi_report`
37
+ - Inference: `from ins_pricing.production import load_predictor_from_config`
38
+ - `from ins_pricing.governance import ModelRegistry, ReleaseManager`
37
39
  6. Reporting
38
40
  - `from ins_pricing.reporting import build_report, write_report, schedule_daily`
39
41
 
40
- ## Import notes
41
-
42
- - `ins_pricing` exposes lightweight lazy imports so that pricing/production/governance
43
- can be used without installing heavy ML dependencies.
42
+ ## Import notes
43
+
44
+ - `ins_pricing` exposes lightweight lazy imports so that pricing/production/governance
45
+ can be used without installing heavy ML dependencies.
44
46
  - Demo notebooks/configs live in the repo under `examples/` and are not shipped
45
47
  in the PyPI package.
46
- - Heavy dependencies are only required when you import or use the related modules:
47
- - BayesOpt: `torch`, `optuna`, `xgboost`, etc.
48
- - Explain: `torch` (gradients), `shap` (SHAP).
49
- - Geo plotting on basemap: `contextily`.
50
- - Plotting: `matplotlib`.
48
+ - Heavy dependencies are only required when you import or use the related modules:
49
+ - BayesOpt: `torch`, `optuna`, `xgboost`, etc.
50
+ - Explain: `torch` (gradients), `shap` (SHAP).
51
+ - Geo plotting on basemap: `contextily`.
52
+ - Plotting: `matplotlib`.
53
+ - Inference: `torch` only when loading FT/ResNet/GNN models.
54
+
55
+ ## Inference interface (new)
56
+
57
+ - `production.inference` provides a small registry-based interface so inference
58
+ does not hard-code model loaders:
59
+ - `ModelSpec` describes the saved model location and config.
60
+ - `PredictorRegistry` lets you plug in custom model loaders.
61
+ - `load_predictor_from_config` remains backward compatible.
62
+
63
+ Example:
64
+
65
+ ```
66
+ from ins_pricing.production import load_predictor_from_config
67
+
68
+ predictor = load_predictor_from_config(
69
+ "config.json",
70
+ "resn",
71
+ device="cuda", # or "mps"/"cpu"
72
+ )
73
+ preds = predictor.predict(df)
74
+ ```
51
75
 
52
- ## Multi-platform and GPU notes
76
+ ## Multi-platform and GPU notes
53
77
 
54
- - Install the correct PyTorch build for your platform/GPU before installing extras.
55
- - Torch Geometric requires platform-specific wheels; follow the official PyG install guide.
56
- - Multi-GPU uses DDP or DataParallel where supported; Windows disables CUDA DDP.
78
+ - Install the correct PyTorch build for your platform/GPU before installing extras.
79
+ - Torch Geometric requires platform-specific wheels; follow the official PyG install guide.
80
+ - Multi-GPU uses DDP or DataParallel where supported; Windows disables CUDA DDP.
81
+ CLI usage prefers `python -m ins_pricing.cli.BayesOpt_entry ...` but the
82
+ direct script path (`python ins_pricing/cli/BayesOpt_entry.py ...`) still works.
57
83
 
58
84
  ## Backward-compatible imports
59
85
 
@@ -1,94 +1,146 @@
1
- from __future__ import annotations
2
-
3
- from importlib import import_module
4
- from pathlib import Path
5
- import sys
6
- import types
7
-
8
- _ROOT_SUBPACKAGES = {
9
- "modelling": "ins_pricing.modelling",
10
- "pricing": "ins_pricing.pricing",
11
- "production": "ins_pricing.production",
12
- "governance": "ins_pricing.governance",
13
- "reporting": "ins_pricing.reporting",
14
- }
15
-
16
- _MODELLING_EXPORTS = {
17
- "BayesOptConfig",
18
- "BayesOptModel",
19
- "IOUtils",
20
- "TrainingUtils",
21
- "free_cuda",
22
- }
23
-
1
+ from __future__ import annotations
2
+
3
+ from importlib import import_module
4
+ from pathlib import Path
5
+ import sys
6
+ import types
7
+
8
+ _ROOT_SUBPACKAGES = {
9
+ "modelling": "ins_pricing.modelling",
10
+ "pricing": "ins_pricing.pricing",
11
+ "production": "ins_pricing.production",
12
+ "governance": "ins_pricing.governance",
13
+ "reporting": "ins_pricing.reporting",
14
+ }
15
+
16
+ _MODELLING_EXPORTS = {
17
+ "BayesOptConfig",
18
+ "BayesOptModel",
19
+ }
20
+
21
+ _BAYESOPT_EXPORTS = {
22
+ "BayesOptConfig",
23
+ "DatasetPreprocessor",
24
+ "OutputManager",
25
+ "VersionManager",
26
+ "BayesOptModel",
27
+ "FeatureTokenizer",
28
+ "FTTransformerCore",
29
+ "FTTransformerSklearn",
30
+ "GraphNeuralNetSklearn",
31
+ "MaskedTabularDataset",
32
+ "ResBlock",
33
+ "ResNetSequential",
34
+ "ResNetSklearn",
35
+ "ScaledTransformerEncoderLayer",
36
+ "SimpleGraphLayer",
37
+ "SimpleGNN",
38
+ "TabularDataset",
39
+ "FTTrainer",
40
+ "GLMTrainer",
41
+ "GNNTrainer",
42
+ "ResNetTrainer",
43
+ "TrainerBase",
44
+ "XGBTrainer",
45
+ "_xgb_cuda_available",
46
+ }
47
+
48
+ _LEGACY_EXPORTS = {
49
+ "IOUtils": "ins_pricing.utils",
50
+ "DeviceManager": "ins_pricing.utils",
51
+ "GPUMemoryManager": "ins_pricing.utils",
52
+ "MetricFactory": "ins_pricing.utils",
53
+ "EPS": "ins_pricing.utils",
54
+ "set_global_seed": "ins_pricing.utils",
55
+ "compute_batch_size": "ins_pricing.utils",
56
+ "tweedie_loss": "ins_pricing.utils",
57
+ "infer_factor_and_cate_list": "ins_pricing.utils",
58
+ "DistributedUtils": "ins_pricing.modelling.bayesopt.utils",
59
+ "TrainingUtils": "ins_pricing.modelling.bayesopt.utils",
60
+ "free_cuda": "ins_pricing.modelling.bayesopt.utils",
61
+ "TorchTrainerMixin": "ins_pricing.modelling.bayesopt.utils",
62
+ }
63
+
24
64
  _LAZY_SUBMODULES = {
25
- "bayesopt": "ins_pricing.modelling.core.bayesopt",
65
+ "bayesopt": "ins_pricing.modelling.bayesopt",
26
66
  "plotting": "ins_pricing.modelling.plotting",
27
67
  "explain": "ins_pricing.modelling.explain",
28
- "BayesOpt": "ins_pricing.modelling.core.BayesOpt",
29
- }
30
-
31
- _PACKAGE_PATHS = {
32
- "bayesopt": Path(__file__).resolve().parent / "modelling" / "core" / "bayesopt",
33
- "plotting": Path(__file__).resolve().parent / "modelling" / "plotting",
34
- "explain": Path(__file__).resolve().parent / "modelling" / "explain",
35
68
  }
36
-
37
- __all__ = sorted(
38
- set(_ROOT_SUBPACKAGES)
39
- | set(_MODELLING_EXPORTS)
40
- | set(_LAZY_SUBMODULES)
41
- )
42
-
43
-
44
- def _lazy_module(name: str, target: str, package_path: Path | None = None) -> types.ModuleType:
45
- proxy = types.ModuleType(name)
46
- if package_path is not None:
47
- proxy.__path__ = [str(package_path)]
48
-
49
- def _load():
50
- module = import_module(target)
51
- sys.modules[name] = module
52
- return module
53
-
54
- def __getattr__(attr: str):
55
- module = _load()
56
- return getattr(module, attr)
57
-
58
- def __dir__() -> list[str]:
59
- module = _load()
60
- return sorted(set(dir(module)))
61
-
62
- proxy.__getattr__ = __getattr__ # type: ignore[attr-defined]
63
- proxy.__dir__ = __dir__ # type: ignore[attr-defined]
64
- return proxy
65
-
66
-
67
- def _install_proxy(alias: str, target: str) -> None:
68
- module_name = f"{__name__}.{alias}"
69
- if module_name in sys.modules:
70
- return
71
- proxy = _lazy_module(module_name, target, _PACKAGE_PATHS.get(alias))
72
- sys.modules[module_name] = proxy
73
- globals()[alias] = proxy
74
-
75
-
76
- for _alias, _target in _LAZY_SUBMODULES.items():
77
- _install_proxy(_alias, _target)
78
-
79
-
80
- def __getattr__(name: str):
81
- if name in _ROOT_SUBPACKAGES:
82
- module = import_module(_ROOT_SUBPACKAGES[name])
83
- globals()[name] = module
84
- return module
85
- if name in _MODELLING_EXPORTS:
86
- module = import_module("ins_pricing.modelling")
87
- value = getattr(module, name)
88
- globals()[name] = value
89
- return value
90
- raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
91
-
92
-
93
- def __dir__() -> list[str]:
94
- return sorted(set(__all__) | set(globals().keys()))
69
+
70
+ _PACKAGE_PATHS = {
71
+ "bayesopt": Path(__file__).resolve().parent / "modelling" / "bayesopt",
72
+ "plotting": Path(__file__).resolve().parent / "modelling" / "plotting",
73
+ "explain": Path(__file__).resolve().parent / "modelling" / "explain",
74
+ }
75
+
76
+ __all__ = sorted(
77
+ set(_ROOT_SUBPACKAGES)
78
+ | set(_MODELLING_EXPORTS)
79
+ | set(_BAYESOPT_EXPORTS)
80
+ | set(_LEGACY_EXPORTS)
81
+ | set(_LAZY_SUBMODULES)
82
+ )
83
+
84
+
85
+ def _lazy_module(name: str, target: str, package_path: Path | None = None) -> types.ModuleType:
86
+ proxy = types.ModuleType(name)
87
+ if package_path is not None:
88
+ proxy.__path__ = [str(package_path)]
89
+
90
+ def _load():
91
+ module = import_module(target)
92
+ sys.modules[name] = module
93
+ return module
94
+
95
+ def __getattr__(attr: str):
96
+ module = _load()
97
+ return getattr(module, attr)
98
+
99
+ def __dir__() -> list[str]:
100
+ module = _load()
101
+ return sorted(set(dir(module)))
102
+
103
+ proxy.__getattr__ = __getattr__ # type: ignore[attr-defined]
104
+ proxy.__dir__ = __dir__ # type: ignore[attr-defined]
105
+ return proxy
106
+
107
+
108
+ def _install_proxy(alias: str, target: str) -> None:
109
+ module_name = f"{__name__}.{alias}"
110
+ if module_name in sys.modules:
111
+ return
112
+ proxy = _lazy_module(module_name, target, _PACKAGE_PATHS.get(alias))
113
+ sys.modules[module_name] = proxy
114
+ globals()[alias] = proxy
115
+
116
+
117
+ for _alias, _target in _LAZY_SUBMODULES.items():
118
+ _install_proxy(_alias, _target)
119
+
120
+
121
+ def __getattr__(name: str):
122
+ if name in _ROOT_SUBPACKAGES:
123
+ module = import_module(_ROOT_SUBPACKAGES[name])
124
+ globals()[name] = module
125
+ return module
126
+ if name in _MODELLING_EXPORTS:
127
+ module = import_module("ins_pricing.modelling")
128
+ value = getattr(module, name)
129
+ globals()[name] = value
130
+ return value
131
+ if name in _BAYESOPT_EXPORTS:
132
+ module = import_module("ins_pricing.modelling.bayesopt")
133
+ value = getattr(module, name)
134
+ globals()[name] = value
135
+ return value
136
+ legacy_module = _LEGACY_EXPORTS.get(name)
137
+ if legacy_module:
138
+ module = import_module(legacy_module)
139
+ value = getattr(module, name)
140
+ globals()[name] = value
141
+ return value
142
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
143
+
144
+
145
+ def __dir__() -> list[str]:
146
+ return sorted(set(__all__) | set(globals().keys()))
@@ -1,56 +1,68 @@
1
- """Thin wrapper for the BayesOpt CLI entry point.
2
-
3
- The main implementation lives in bayesopt_entry_runner.py.
4
- """
5
-
6
- from __future__ import annotations
7
-
1
+ """Thin wrapper for the BayesOpt CLI entry point.
2
+
3
+ The main implementation lives in bayesopt_entry_runner.py.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
8
  from pathlib import Path
9
+ import importlib.util
9
10
  import json
10
11
  import os
11
12
  import sys
12
13
 
13
- if __package__ in {None, ""}:
14
- repo_root = Path(__file__).resolve().parents[2]
15
- if str(repo_root) not in sys.path:
16
- sys.path.insert(0, str(repo_root))
17
-
18
- def _apply_env_from_config(argv: list[str]) -> None:
19
- if "--config-json" not in argv:
14
+ def _ensure_repo_root() -> None:
15
+ if __package__ not in {None, ""}:
20
16
  return
21
- idx = argv.index("--config-json")
22
- if idx + 1 >= len(argv):
17
+ if importlib.util.find_spec("ins_pricing") is not None:
23
18
  return
24
- raw_path = argv[idx + 1]
25
- try:
26
- cfg_path = Path(raw_path).expanduser()
27
- if not cfg_path.is_absolute():
28
- cfg_path = cfg_path.resolve()
29
- if not cfg_path.exists():
30
- script_dir = Path(__file__).resolve().parents[1]
31
- candidate = (script_dir / raw_path).resolve()
32
- if candidate.exists():
33
- cfg_path = candidate
34
- if not cfg_path.exists():
35
- return
36
- cfg = json.loads(cfg_path.read_text(encoding="utf-8", errors="replace"))
37
- env = cfg.get("env", {})
38
- if isinstance(env, dict):
39
- for key, value in env.items():
40
- if key is None:
41
- continue
42
- os.environ.setdefault(str(key), str(value))
43
- except Exception:
19
+ bootstrap_path = Path(__file__).resolve().parents[1] / "utils" / "bootstrap.py"
20
+ spec = importlib.util.spec_from_file_location("ins_pricing.cli.utils.bootstrap", bootstrap_path)
21
+ if spec is None or spec.loader is None:
44
22
  return
23
+ module = importlib.util.module_from_spec(spec)
24
+ spec.loader.exec_module(module)
25
+ module.ensure_repo_root()
45
26
 
46
- _apply_env_from_config(sys.argv)
47
-
48
- try:
49
- from .bayesopt_entry_runner import main
50
- except Exception: # pragma: no cover
51
- from ins_pricing.cli.bayesopt_entry_runner import main
52
-
53
- __all__ = ["main"]
54
27
 
55
- if __name__ == "__main__":
56
- main()
28
+ _ensure_repo_root()
29
+
30
+ def _apply_env_from_config(argv: list[str]) -> None:
31
+ if "--config-json" not in argv:
32
+ return
33
+ idx = argv.index("--config-json")
34
+ if idx + 1 >= len(argv):
35
+ return
36
+ raw_path = argv[idx + 1]
37
+ try:
38
+ cfg_path = Path(raw_path).expanduser()
39
+ if not cfg_path.is_absolute():
40
+ cfg_path = cfg_path.resolve()
41
+ if not cfg_path.exists():
42
+ script_dir = Path(__file__).resolve().parents[1]
43
+ candidate = (script_dir / raw_path).resolve()
44
+ if candidate.exists():
45
+ cfg_path = candidate
46
+ if not cfg_path.exists():
47
+ return
48
+ cfg = json.loads(cfg_path.read_text(encoding="utf-8", errors="replace"))
49
+ env = cfg.get("env", {})
50
+ if isinstance(env, dict):
51
+ for key, value in env.items():
52
+ if key is None:
53
+ continue
54
+ os.environ.setdefault(str(key), str(value))
55
+ except Exception:
56
+ return
57
+
58
+ _apply_env_from_config(sys.argv)
59
+
60
+ try:
61
+ from ins_pricing.cli.bayesopt_entry_runner import main
62
+ except Exception: # pragma: no cover
63
+ from ins_pricing.cli.bayesopt_entry_runner import main
64
+
65
+ __all__ = ["main"]
66
+
67
+ if __name__ == "__main__":
68
+ main()
@@ -1,5 +1,4 @@
1
- """Incremental training harness built on top of ``ins_pricing.bayesopt``
2
- (compat via ``BayesOpt.py``).
1
+ """Incremental training harness built on top of ``ins_pricing.bayesopt``.
3
2
 
4
3
  This utility lets you append new observations to an existing dataset,
5
4
  reuse previously tuned hyperparameters and retrain a subset of models
@@ -17,13 +16,26 @@ Example:
17
16
 
18
17
  from __future__ import annotations
19
18
 
20
- from pathlib import Path
21
- import sys
22
-
23
- if __package__ in {None, ""}:
24
- repo_root = Path(__file__).resolve().parents[2]
25
- if str(repo_root) not in sys.path:
26
- sys.path.insert(0, str(repo_root))
19
+ from pathlib import Path
20
+ import importlib.util
21
+ import sys
22
+
23
+
24
+ def _ensure_repo_root() -> None:
25
+ if __package__ not in {None, ""}:
26
+ return
27
+ if importlib.util.find_spec("ins_pricing") is not None:
28
+ return
29
+ bootstrap_path = Path(__file__).resolve().parents[1] / "utils" / "bootstrap.py"
30
+ spec = importlib.util.spec_from_file_location("ins_pricing.cli.utils.bootstrap", bootstrap_path)
31
+ if spec is None or spec.loader is None:
32
+ return
33
+ module = importlib.util.module_from_spec(spec)
34
+ spec.loader.exec_module(module)
35
+ module.ensure_repo_root()
36
+
37
+
38
+ _ensure_repo_root()
27
39
 
28
40
  import argparse
29
41
  import json
@@ -31,102 +43,35 @@ from dataclasses import asdict
31
43
  from datetime import datetime
32
44
  from typing import Any, Dict, List, Optional, Sequence, Tuple
33
45
 
34
- import pandas as pd
35
-
36
- try:
37
- from .. import bayesopt as ropt # type: ignore
38
- from .utils.cli_common import ( # type: ignore
39
- PLOT_MODEL_LABELS,
40
- PYTORCH_TRAINERS,
41
- build_model_names,
42
- dedupe_preserve_order,
43
- load_dataset,
44
- parse_model_pairs,
45
- resolve_data_path,
46
- resolve_path,
47
- split_train_test,
48
- )
49
- from .utils.cli_config import ( # type: ignore
50
- add_config_json_arg,
51
- resolve_and_load_config,
52
- resolve_data_config,
53
- resolve_split_config,
54
- resolve_runtime_config,
55
- resolve_output_dirs,
56
- )
57
- except Exception: # pragma: no cover
58
- try:
59
- import bayesopt as ropt # type: ignore
60
- from utils.cli_common import ( # type: ignore
61
- PLOT_MODEL_LABELS,
62
- PYTORCH_TRAINERS,
63
- build_model_names,
64
- dedupe_preserve_order,
65
- load_dataset,
66
- parse_model_pairs,
67
- resolve_data_path,
68
- resolve_path,
69
- split_train_test,
70
- )
71
- from utils.cli_config import ( # type: ignore
72
- add_config_json_arg,
73
- resolve_and_load_config,
74
- resolve_data_config,
75
- resolve_split_config,
76
- resolve_runtime_config,
77
- resolve_output_dirs,
78
- )
79
- except Exception:
80
- try:
81
- import ins_pricing.modelling.core.bayesopt as ropt # type: ignore
82
- from ins_pricing.cli.utils.cli_common import ( # type: ignore
83
- PLOT_MODEL_LABELS,
84
- PYTORCH_TRAINERS,
85
- build_model_names,
86
- dedupe_preserve_order,
87
- load_dataset,
88
- parse_model_pairs,
89
- resolve_data_path,
90
- resolve_path,
91
- split_train_test,
92
- )
93
- from ins_pricing.cli.utils.cli_config import ( # type: ignore
94
- add_config_json_arg,
95
- resolve_and_load_config,
96
- resolve_data_config,
97
- resolve_split_config,
98
- resolve_runtime_config,
99
- resolve_output_dirs,
100
- )
101
- except Exception:
102
- import BayesOpt as ropt # type: ignore
103
- from utils.cli_common import ( # type: ignore
104
- PLOT_MODEL_LABELS,
105
- PYTORCH_TRAINERS,
106
- build_model_names,
107
- dedupe_preserve_order,
108
- load_dataset,
109
- parse_model_pairs,
110
- resolve_data_path,
111
- resolve_path,
112
- split_train_test,
113
- )
114
- from utils.cli_config import ( # type: ignore
115
- add_config_json_arg,
116
- resolve_and_load_config,
117
- resolve_data_config,
118
- resolve_split_config,
119
- resolve_runtime_config,
120
- resolve_output_dirs,
121
- )
122
-
123
- try:
124
- from .utils.run_logging import configure_run_logging # type: ignore
125
- except Exception: # pragma: no cover
126
- try:
127
- from utils.run_logging import configure_run_logging # type: ignore
128
- except Exception: # pragma: no cover
129
- configure_run_logging = None # type: ignore
46
+ import pandas as pd
47
+
48
+ from ins_pricing.cli.utils.import_resolver import resolve_imports, setup_sys_path
49
+
50
+ setup_sys_path()
51
+ _imports = resolve_imports()
52
+
53
+ ropt = _imports.bayesopt
54
+ if ropt is None: # pragma: no cover
55
+ raise ImportError("Failed to resolve ins_pricing.bayesopt for incremental CLI.")
56
+
57
+ PLOT_MODEL_LABELS = _imports.PLOT_MODEL_LABELS
58
+ PYTORCH_TRAINERS = _imports.PYTORCH_TRAINERS
59
+ build_model_names = _imports.build_model_names
60
+ dedupe_preserve_order = _imports.dedupe_preserve_order
61
+ load_dataset = _imports.load_dataset
62
+ parse_model_pairs = _imports.parse_model_pairs
63
+ resolve_data_path = _imports.resolve_data_path
64
+ resolve_path = _imports.resolve_path
65
+ split_train_test = _imports.split_train_test
66
+
67
+ add_config_json_arg = _imports.add_config_json_arg
68
+ resolve_and_load_config = _imports.resolve_and_load_config
69
+ resolve_data_config = _imports.resolve_data_config
70
+ resolve_split_config = _imports.resolve_split_config
71
+ resolve_runtime_config = _imports.resolve_runtime_config
72
+ resolve_output_dirs = _imports.resolve_output_dirs
73
+
74
+ configure_run_logging = _imports.configure_run_logging
130
75
 
131
76
 
132
77
  def _log(message: str) -> None:
@@ -488,9 +433,20 @@ class IncrementalUpdateRunner:
488
433
  self.prediction_cache_dir = runtime_cfg["prediction_cache_dir"]
489
434
  self.prediction_cache_format = runtime_cfg["prediction_cache_format"]
490
435
  self.plot_path_style = runtime_cfg["plot_path_style"]
491
- self.xgb_max_depth_max = runtime_cfg["xgb_max_depth_max"]
492
- self.xgb_n_estimators_max = runtime_cfg["xgb_n_estimators_max"]
493
- self.optuna_storage = runtime_cfg["optuna_storage"]
436
+ self.xgb_max_depth_max = runtime_cfg["xgb_max_depth_max"]
437
+ self.xgb_n_estimators_max = runtime_cfg["xgb_n_estimators_max"]
438
+ self.xgb_gpu_id = runtime_cfg["xgb_gpu_id"]
439
+ self.xgb_cleanup_per_fold = runtime_cfg["xgb_cleanup_per_fold"]
440
+ self.xgb_cleanup_synchronize = runtime_cfg["xgb_cleanup_synchronize"]
441
+ self.xgb_use_dmatrix = runtime_cfg["xgb_use_dmatrix"]
442
+ self.ft_cleanup_per_fold = runtime_cfg["ft_cleanup_per_fold"]
443
+ self.ft_cleanup_synchronize = runtime_cfg["ft_cleanup_synchronize"]
444
+ self.resn_cleanup_per_fold = runtime_cfg["resn_cleanup_per_fold"]
445
+ self.resn_cleanup_synchronize = runtime_cfg["resn_cleanup_synchronize"]
446
+ self.gnn_cleanup_per_fold = runtime_cfg["gnn_cleanup_per_fold"]
447
+ self.gnn_cleanup_synchronize = runtime_cfg["gnn_cleanup_synchronize"]
448
+ self.optuna_cleanup_synchronize = runtime_cfg["optuna_cleanup_synchronize"]
449
+ self.optuna_storage = runtime_cfg["optuna_storage"]
494
450
  self.optuna_study_prefix = runtime_cfg["optuna_study_prefix"]
495
451
  self.best_params_files = runtime_cfg["best_params_files"]
496
452
  self.reuse_best_params = runtime_cfg["reuse_best_params"]
@@ -659,8 +615,19 @@ class IncrementalUpdateRunner:
659
615
  use_ft_ddp=self.cfg.get("use_ft_ddp", False),
660
616
  use_gnn_ddp=self.cfg.get("use_gnn_ddp", False),
661
617
  output_dir=str(self.output_root) if self.output_root else None,
662
- xgb_max_depth_max=self.xgb_max_depth_max,
663
- xgb_n_estimators_max=self.xgb_n_estimators_max,
618
+ xgb_max_depth_max=self.xgb_max_depth_max,
619
+ xgb_n_estimators_max=self.xgb_n_estimators_max,
620
+ xgb_gpu_id=self.xgb_gpu_id,
621
+ xgb_cleanup_per_fold=self.xgb_cleanup_per_fold,
622
+ xgb_cleanup_synchronize=self.xgb_cleanup_synchronize,
623
+ xgb_use_dmatrix=self.xgb_use_dmatrix,
624
+ ft_cleanup_per_fold=self.ft_cleanup_per_fold,
625
+ ft_cleanup_synchronize=self.ft_cleanup_synchronize,
626
+ resn_cleanup_per_fold=self.resn_cleanup_per_fold,
627
+ resn_cleanup_synchronize=self.resn_cleanup_synchronize,
628
+ gnn_cleanup_per_fold=self.gnn_cleanup_per_fold,
629
+ gnn_cleanup_synchronize=self.gnn_cleanup_synchronize,
630
+ optuna_cleanup_synchronize=self.optuna_cleanup_synchronize,
664
631
  resn_weight_decay=self.cfg.get("resn_weight_decay"),
665
632
  final_ensemble=bool(self.cfg.get("final_ensemble", False)),
666
633
  final_ensemble_k=int(self.cfg.get("final_ensemble_k", 3)),