morphtree 2.1.0__py3-none-win_amd64.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.
- morphtree/__init__.py +28 -0
- morphtree/__main__.py +3 -0
- morphtree/_experimental/__init__.py +1 -0
- morphtree/_experimental/admission.py +364 -0
- morphtree/_experimental/base.py +215 -0
- morphtree/_experimental/component_cache_v2.py +263 -0
- morphtree/_experimental/evolution_report.py +307 -0
- morphtree/_experimental/execution_v2.py +697 -0
- morphtree/_experimental/facade.py +289 -0
- morphtree/_experimental/integrated.py +748 -0
- morphtree/_experimental/learning.py +418 -0
- morphtree/_experimental/manifest.json +204 -0
- morphtree/_experimental/numeric_fixture.py +21 -0
- morphtree/_experimental/parameter_contract.py +38 -0
- morphtree/_experimental/postfit.py +51 -0
- morphtree/_experimental/preprocessing.py +133 -0
- morphtree/_experimental/processes.py +191 -0
- morphtree/_experimental/producer.py +542 -0
- morphtree/_experimental/product.py +156 -0
- morphtree/_experimental/product_cli.py +43 -0
- morphtree/_experimental/roundtrip_v3.py +311 -0
- morphtree/_experimental/runtime_io.py +65 -0
- morphtree/_experimental/sampling.py +26 -0
- morphtree/_experimental/support.py +281 -0
- morphtree/_experimental/target.py +59 -0
- morphtree/_experimental/training.py +53 -0
- morphtree/_experimental/worker.py +682 -0
- morphtree/_installed.py +17 -0
- morphtree/_native/__init__.py +1 -0
- morphtree/_native/bin/win_amd64/morphtree_kernels.dll +0 -0
- morphtree/_native/buffers.py +82 -0
- morphtree/_native/loader.py +39 -0
- morphtree/_native/manifest.json +29 -0
- morphtree/_native/runtime.py +48 -0
- morphtree/_native/src/histogram.c +61 -0
- morphtree/_native/src/traversal.c +51 -0
- morphtree/api.py +388 -0
- morphtree/api_compat.py +65 -0
- morphtree/backend.py +162 -0
- morphtree/booster.py +252 -0
- morphtree/cli.py +52 -0
- morphtree/config.py +262 -0
- morphtree/control.py +20 -0
- morphtree/data.py +300 -0
- morphtree/diagnostics.py +158 -0
- morphtree/estimators.py +156 -0
- morphtree/examples.py +25 -0
- morphtree/exporting.py +224 -0
- morphtree/legacy_artifacts.py +32 -0
- morphtree/metrics.py +156 -0
- morphtree/model.py +1010 -0
- morphtree/mutations.py +205 -0
- morphtree/native_lab_backend.py +79 -0
- morphtree/numpy_backend.py +180 -0
- morphtree/optuna_tuner.py +154 -0
- morphtree/persistence.py +414 -0
- morphtree/prediction_output.py +35 -0
- morphtree/prepared_bins.py +82 -0
- morphtree/public.py +106 -0
- morphtree/resource_plan.py +170 -0
- morphtree/scalable.py +781 -0
- morphtree/scalable_backend.py +74 -0
- morphtree/scalable_checkpoint.py +129 -0
- morphtree/scalable_data.py +255 -0
- morphtree/scalable_receipts.py +92 -0
- morphtree/scalable_target.py +68 -0
- morphtree/scalable_variants.py +133 -0
- morphtree/sklearn_view.py +79 -0
- morphtree/source_markers.py +25 -0
- morphtree/species.py +47 -0
- morphtree/temporary.py +65 -0
- morphtree/training_fragment.py +130 -0
- morphtree/tree.py +231 -0
- morphtree/tuning.py +150 -0
- morphtree-2.1.0.dist-info/METADATA +212 -0
- morphtree-2.1.0.dist-info/RECORD +79 -0
- morphtree-2.1.0.dist-info/WHEEL +4 -0
- morphtree-2.1.0.dist-info/entry_points.txt +2 -0
- morphtree-2.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
from .execution_v2 import SearchBudgetExhausted
|
|
2
|
+
import copy, importlib, importlib.util, json, math, random, tempfile, time
|
|
3
|
+
from ..temporary import OwnedTemporaryDirectory
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from dataclasses import asdict, replace
|
|
6
|
+
from morphtree.config import AlgorithmGenome, HyperParams
|
|
7
|
+
from morphtree.persistence import read_json, write_json, LoadLimits
|
|
8
|
+
from .runtime_io import artifact_path, configure_temp, reference
|
|
9
|
+
from .admission import digest, sha
|
|
10
|
+
from .support import FamilyChoice, TaskFinalizer, risk
|
|
11
|
+
from .parameter_contract import admit_space
|
|
12
|
+
from .base import Base as Previous, PARAMS, _payloads
|
|
13
|
+
from .preprocessing import TrainEncoder, _m26_rows
|
|
14
|
+
from .training import NativeExecutor, TrainingNotAdmitted
|
|
15
|
+
from .target import detect_target, _split, _NamedRows
|
|
16
|
+
|
|
17
|
+
class BudgetExhausted(RuntimeError):
|
|
18
|
+
"""Finite opportunity cap; never convergence or a fresh budget."""
|
|
19
|
+
|
|
20
|
+
class StopRequested(RuntimeError):
|
|
21
|
+
"""Explicit STOP; never a recoverable timeout."""
|
|
22
|
+
|
|
23
|
+
class VariantUnavailable(ValueError):
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
def stop_reason(*, event, completed_proposals=0, improved=False, full_neighborhood_verified=False):
|
|
27
|
+
"""Typed operational semantics, not a fitted stagnation detector."""
|
|
28
|
+
direct = {'planned': 'PLANNED_SEARCH_COMPLETE', 'no_actions': 'NO_ADMISSIBLE_CORRECTIVE_ACTION', 'budget': 'BUDGET_EXHAUSTED', 'timeout': 'TIMEOUT', 'stop': 'STOP_REQUESTED', 'error': 'ERROR_OR_INTERRUPTION', 'not_admitted': 'EXECUTION_NOT_ADMITTED'}
|
|
29
|
+
if event in direct:
|
|
30
|
+
return direct[event]
|
|
31
|
+
if type(completed_proposals) is not int or completed_proposals < 1 or type(improved) is not bool:
|
|
32
|
+
raise ValueError('A completed comparison is required before a stall claim')
|
|
33
|
+
if event == 'structural' and (not improved):
|
|
34
|
+
return 'STRUCTURAL_NO_IMPROVEMENT'
|
|
35
|
+
if event == 'family' and (not improved) and (full_neighborhood_verified is True):
|
|
36
|
+
return 'FAMILY_SEARCH_STALLED'
|
|
37
|
+
raise ValueError('No evidence of the requested stall')
|
|
38
|
+
|
|
39
|
+
def mutation_admission(mode):
|
|
40
|
+
"""Reuse negative knowledge: no scientifically admitted automatic operator.
|
|
41
|
+
|
|
42
|
+
This admission decision is not a diagnostic measurement. No labels, OOF,
|
|
43
|
+
SEARCH or final GUARD are accepted by this function.
|
|
44
|
+
"""
|
|
45
|
+
if mode not in ('none', 'auto'):
|
|
46
|
+
raise ValueError('Only none/auto morphing admitted')
|
|
47
|
+
return {'requested': mode, 'diagnosis_executed': False, 'diagnosis_status': 'OMITTED_DISABLED' if mode == 'none' else 'OMITTED_NO_ADMITTED_CORRECTION', 'information_acquisition': {'new_OOF': 0, 'new_fits': 0, 'measured_seconds': None}, 'eligible_operators': [], 'excluded_operators': [{'id': 'MORPH-013-atomic-trigger', 'reason': 'FAILED_STRONG_CONTROLS'}, {'id': 'MORPH-014-015-simple-mean', 'reason': 'FAILED_BEST_PARENT_CONTROLS'}, {'id': 'historical-lookahead', 'reason': 'NO_INDEPENDENT_DEFAULT_UTILITY'}], 'attempted': [], 'accepted': [], 'rollback': [], 'decision': 'DISABLED' if mode == 'none' else 'RETAIN_CURRENT_NO_ADMITTED_OPERATOR', 'rediagnosis': 'NOT_EXECUTED', 'utility': 'NOT_DEMONSTRATED'}
|
|
48
|
+
|
|
49
|
+
class LearningControl(Previous):
|
|
50
|
+
"""Private three-task automatic facade, not a production estimator.
|
|
51
|
+
|
|
52
|
+
balanced resolves to serial, 30s, boost8/bag8, and at most four numeric
|
|
53
|
+
trials ONLY with a separately qualified executor. Without such admission,
|
|
54
|
+
auto skips tuning and explicit optuna refuses before learning. No automatic
|
|
55
|
+
OOF, structural mutation, composition, refit or final GUARD is enabled.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
def __init__(self, *, task='auto', families='auto', morphing='auto', tuning='auto', preset='balanced', metric='auto', time_budget='auto', n_trials='auto', n_jobs='auto', random_state=None, verbose=0, capacity=None):
|
|
59
|
+
self.capacity = copy.deepcopy(capacity)
|
|
60
|
+
super().__init__(task=task, families=families, morphing=morphing, tuning=tuning, preset=preset, metric=metric, time_budget=time_budget, n_trials=n_trials, n_jobs=n_jobs, random_state=random_state, verbose=verbose)
|
|
61
|
+
|
|
62
|
+
def _validate(self):
|
|
63
|
+
super()._validate()
|
|
64
|
+
if self.capacity is not None:
|
|
65
|
+
if type(self.capacity) is not dict or not set(self.capacity) <= {'max_leaves', 'max_depth'}:
|
|
66
|
+
raise ValueError('capacity supports only max_leaves/max_depth; no inactive options')
|
|
67
|
+
for name, value in self.capacity.items():
|
|
68
|
+
if type(value) is not int or not 1 <= value <= {'max_leaves': 16, 'max_depth': 8}[name]:
|
|
69
|
+
raise ValueError('Finite integer structural capacity required')
|
|
70
|
+
|
|
71
|
+
def get_params(self, deep=True):
|
|
72
|
+
return copy.deepcopy({k: getattr(self, k) for k in (*PARAMS, 'capacity')})
|
|
73
|
+
|
|
74
|
+
def set_params(self, **values):
|
|
75
|
+
if set(values) - set(self.get_params()):
|
|
76
|
+
raise ValueError('Unknown estimator parameter')
|
|
77
|
+
new = type(self)(**self.get_params() | values)
|
|
78
|
+
self.__dict__ = new.__dict__
|
|
79
|
+
return self
|
|
80
|
+
|
|
81
|
+
def _make_executor(self):
|
|
82
|
+
return NativeExecutor()
|
|
83
|
+
|
|
84
|
+
def _numeric_admitted(self, executor):
|
|
85
|
+
return False
|
|
86
|
+
|
|
87
|
+
def _optional_optuna(self):
|
|
88
|
+
return importlib.util.find_spec('optuna') is not None
|
|
89
|
+
|
|
90
|
+
def _load_optuna(self):
|
|
91
|
+
return importlib.import_module('optuna')
|
|
92
|
+
|
|
93
|
+
def _numeric_plan(self, executor):
|
|
94
|
+
if self.tuning == 'none':
|
|
95
|
+
return (None, 'DISABLED', 0)
|
|
96
|
+
if not self._optional_optuna():
|
|
97
|
+
if self.tuning == 'optuna':
|
|
98
|
+
raise ImportError('tuning="optuna" requires optional Optuna before any learning')
|
|
99
|
+
return (None, 'AUTO_SKIPPED_DEPENDENCY', 0)
|
|
100
|
+
if not self._numeric_admitted(executor):
|
|
101
|
+
if self.tuning == 'optuna':
|
|
102
|
+
raise TrainingNotAdmitted('Explicit numeric execution needs new source-bound fit/trial admission')
|
|
103
|
+
return (None, 'AUTO_SKIPPED_NUMERIC_ADMISSION', 0)
|
|
104
|
+
return (self._load_optuna(), 'ADMITTED', 2 if self.n_trials == 'auto' else self.n_trials)
|
|
105
|
+
|
|
106
|
+
def _log(self, events, start, operation, **values):
|
|
107
|
+
event = {'operation': operation, 'seconds_since_start': time.monotonic() - start, **values}
|
|
108
|
+
self._record_event(copy.deepcopy(event))
|
|
109
|
+
events.append(event)
|
|
110
|
+
|
|
111
|
+
def fit(self, X, y):
|
|
112
|
+
self._validate()
|
|
113
|
+
start = time.monotonic()
|
|
114
|
+
cpu = time.process_time()
|
|
115
|
+
events = []
|
|
116
|
+
attempt = {'status': 'INTENT', 'events': events, 'logical_family_requests': 0, 'numeric_callback_requests': 0, 'physical_fits': 'UNKNOWN_AT_UNADMITTED_BOUNDARY', 'best_verified_anchor': None, 'stop_reason': None}
|
|
117
|
+
self.last_attempt_ = attempt
|
|
118
|
+
|
|
119
|
+
def log(operation, **values):
|
|
120
|
+
self._log(events, start, operation, **values)
|
|
121
|
+
|
|
122
|
+
def check():
|
|
123
|
+
self._execution_check()
|
|
124
|
+
if time.monotonic() - start >= (150.0 if self.time_budget == 'auto' else self.time_budget):
|
|
125
|
+
raise TimeoutError('Finite operational deadline, not an algorithmic stall')
|
|
126
|
+
try:
|
|
127
|
+
executor = self._make_executor()
|
|
128
|
+
optuna, tuning_status, trial_cap = self._numeric_plan(executor)
|
|
129
|
+
check()
|
|
130
|
+
rows, names = _m26_rows(X)
|
|
131
|
+
task, targets, classes = detect_target(y, self.task)
|
|
132
|
+
if len(rows) != len(targets):
|
|
133
|
+
raise ValueError('Aligned X/y required')
|
|
134
|
+
metric = 'mse' if task == 'regression' else 'logloss'
|
|
135
|
+
if self.metric not in ('auto', metric):
|
|
136
|
+
raise ValueError('Metric is inconsistent with task')
|
|
137
|
+
seed = self.random_state if self.random_state is not None else random.SystemRandom().randrange(2 ** 31)
|
|
138
|
+
ti, si = _split(targets, task, seed)
|
|
139
|
+
log('split', TRAIN=ti, SEARCH=si, GUARD_used=False)
|
|
140
|
+
encoder = TrainEncoder().fit([rows[i] for i in ti])
|
|
141
|
+
encoder.state_['names'] = names
|
|
142
|
+
if encoder.width_ * len(rows) > 2000000:
|
|
143
|
+
raise ValueError('Expanded input exceeds finite 2000000-cell cap')
|
|
144
|
+
trainX = encoder.transform(_NamedRows([rows[i] for i in ti], names))
|
|
145
|
+
searchX = encoder.transform(_NamedRows([rows[i] for i in si], names))
|
|
146
|
+
ty = [targets[i] for i in ti]
|
|
147
|
+
sy = [targets[i] for i in si]
|
|
148
|
+
selection = {'role': 'SEARCH', 'ids': ['SEARCH:' + str(i) for i in si], 'X': searchX, 'y': sy}
|
|
149
|
+
identity = {'TRAIN': digest({'X': trainX, 'y': ty, 'ids': ti}), 'SEARCH': digest(selection)}
|
|
150
|
+
params = HyperParams(n_estimators=2, max_leaves=8, max_depth=4, max_bins=15, min_samples_leaf=2, row_fraction=1.0)
|
|
151
|
+
if self.capacity:
|
|
152
|
+
params = replace(params, **self.capacity)
|
|
153
|
+
params = self._parameters(params)
|
|
154
|
+
families = ['boost', 'bag'] if self.families == 'auto' else [self.families]
|
|
155
|
+
models = {}
|
|
156
|
+
packets = {}
|
|
157
|
+
completed = []
|
|
158
|
+
trials = []
|
|
159
|
+
|
|
160
|
+
def acquire(name, family, p, genome=None):
|
|
161
|
+
genome = AlgorithmGenome() if genome is None else genome
|
|
162
|
+
check()
|
|
163
|
+
if attempt['logical_family_requests'] >= len(families) + trial_cap + self._extra_opportunities():
|
|
164
|
+
raise BudgetExhausted('Finite family/trial opportunities exhausted')
|
|
165
|
+
self._admit_learning_batch(task, family, p, 'COMPLETE_FAMILY_REQUEST')
|
|
166
|
+
attempt['logical_family_requests'] += 1
|
|
167
|
+
log('learning_request', id=name, family=family, params=asdict(p))
|
|
168
|
+
model = executor.fit_family(task, family, trainX, ty, seed=seed, params=p, check=check, genome=genome, identity={**identity, 'preprocessing': encoder.to_dict(), 'seed': seed, 'task': task, 'family': family, 'TRAIN_ids': ['ROW:' + str(i) for i in ti], 'actual_TRAIN_X': trainX, 'actual_TRAIN_y': ty})
|
|
169
|
+
check()
|
|
170
|
+
payload = _payloads(model)
|
|
171
|
+
packet = {'id': name, 'task': task, 'family': family, 'recipe': self._structure_packet(genome, classes, len(model.components), encoder), 'learning_identity': identity, 'params': asdict(p), 'artifact_sha256': digest(payload)}
|
|
172
|
+
models[name] = model
|
|
173
|
+
packets[name] = packet
|
|
174
|
+
completed.append(name)
|
|
175
|
+
self._capture_report_packet(packet, model, selection, {'X': trainX, 'y': ty})
|
|
176
|
+
log('learning_completed', id=name, boundary=executor.evidence_level, packet=copy.deepcopy(packet))
|
|
177
|
+
return packet
|
|
178
|
+
|
|
179
|
+
def verify(packet, search):
|
|
180
|
+
check()
|
|
181
|
+
name = packet['id']
|
|
182
|
+
if packet != packets[name] or search != selection or digest(_payloads(models[name])) != packet['artifact_sha256']:
|
|
183
|
+
raise ValueError('Changed completed native model, frozen form or SEARCH')
|
|
184
|
+
return models[name].probabilities_or_values(search['X'])
|
|
185
|
+
anchor = acquire(families[0], families[0], params)
|
|
186
|
+
chooser = FamilyChoice(anchor, selection, checkpoint=lambda e: log('family_selection', **e), verify=verify)
|
|
187
|
+
attempt['best_verified_anchor'] = copy.deepcopy(chooser.best['packet'])
|
|
188
|
+
try:
|
|
189
|
+
result = chooser.run(acquire(families[1], families[1], params)) if len(families) > 1 else chooser.best
|
|
190
|
+
except SearchBudgetExhausted as budget_error:
|
|
191
|
+
self._budget_stopped('FAMILY', attempt['best_verified_anchor'], attempt, log, budget_error)
|
|
192
|
+
result = chooser.best
|
|
193
|
+
selected = result['packet']
|
|
194
|
+
attempt['best_verified_anchor'] = copy.deepcopy(selected)
|
|
195
|
+
morph = self._diagnose({'OOF': None, 'admitted_operators': []})
|
|
196
|
+
log('mutation_admission', **morph)
|
|
197
|
+
selected, result = self._structural_stage(selected, result, acquire, verify, selection, params, log, attempt)
|
|
198
|
+
pure = copy.deepcopy(selected)
|
|
199
|
+
pure_prediction = copy.deepcopy(result['prediction'])
|
|
200
|
+
frozen_result = TaskFinalizer(selected, selection, numeric_fields=[], max_trials=0, verify=verify, checkpoint=lambda e: log('finalization', **e)).run(None)
|
|
201
|
+
log('structure_frozen', sha256=digest(selected['recipe']), packet=copy.deepcopy(selected), numeric_budget=trial_cap)
|
|
202
|
+
self._begin_numeric_window()
|
|
203
|
+
try:
|
|
204
|
+
if trial_cap and self._search_budget_open():
|
|
205
|
+
space = {'l2': [0.1, 10.0], 'min_samples_leaf': [1, 8]}
|
|
206
|
+
if selected['family'] == 'boost':
|
|
207
|
+
space['learning_rate'] = [0.03, 0.3]
|
|
208
|
+
space = admit_space(space, family=selected['family'], task=task, genome=AlgorithmGenome(**selected['recipe']['genome']))['space']
|
|
209
|
+
|
|
210
|
+
def numeric_checkpoint(e):
|
|
211
|
+
log('numeric_selection', **e)
|
|
212
|
+
if e['status'] == 'COMPLETED':
|
|
213
|
+
attempt['best_verified_anchor'] = copy.deepcopy(packets[e['retained']])
|
|
214
|
+
finalizer = TaskFinalizer(selected, selection, numeric_fields=list(space), max_trials=trial_cap, verify=verify, checkpoint=numeric_checkpoint)
|
|
215
|
+
study = optuna.create_study(direction='minimize', sampler=optuna.samplers.TPESampler(seed=seed, n_startup_trials=2))
|
|
216
|
+
frozen = digest({'family': selected['family'], 'recipe': selected['recipe'], 'fixed_params': {k: v for k, v in selected['params'].items() if k not in space}})
|
|
217
|
+
log('structure_frozen', sha256=frozen, space=space)
|
|
218
|
+
|
|
219
|
+
def propose(i, frozen_anchor):
|
|
220
|
+
check()
|
|
221
|
+
attempt['numeric_callback_requests'] += 1
|
|
222
|
+
self._admit_learning_batch(task, frozen_anchor['family'], HyperParams(**frozen_anchor['params']), 'NUMERIC_BEFORE_ASK')
|
|
223
|
+
trial = study.ask()
|
|
224
|
+
try:
|
|
225
|
+
values = {n: trial.suggest_int(n, *b) if n == 'min_samples_leaf' else trial.suggest_float(n, *b, log=True) for n, b in space.items()}
|
|
226
|
+
p = replace(HyperParams(**frozen_anchor['params']), **values)
|
|
227
|
+
candidate = acquire('trial:' + str(i), frozen_anchor['family'], p, AlgorithmGenome(**frozen_anchor['recipe']['genome']))
|
|
228
|
+
loss = finalizer._verified(candidate)['loss']
|
|
229
|
+
study.tell(trial, loss)
|
|
230
|
+
trials.append({'number': trial.number, 'state': 'COMPLETE', 'params': values, 'SEARCH_primary': loss})
|
|
231
|
+
return candidate
|
|
232
|
+
except BaseException as primary_error:
|
|
233
|
+
if isinstance(primary_error, SearchBudgetExhausted):
|
|
234
|
+
self._close_search_budget('NUMERIC_SEARCH_WINDOW_EXHAUSTED')
|
|
235
|
+
try:
|
|
236
|
+
study.tell(trial, state=optuna.trial.TrialState.FAIL)
|
|
237
|
+
except BaseException as cleanup_error:
|
|
238
|
+
log('numeric_trial_cleanup_failed', number=trial.number, error=type(cleanup_error).__name__, original_error=type(primary_error).__name__, state='UNRESOLVED')
|
|
239
|
+
raise
|
|
240
|
+
selected = finalizer.run(propose)['packet']
|
|
241
|
+
attempt['best_verified_anchor'] = copy.deepcopy(selected)
|
|
242
|
+
tuning_status = 'OPTUNA_CALLBACKS_COMPLETE'
|
|
243
|
+
elif trial_cap:
|
|
244
|
+
tuning_status = 'SKIPPED_SEARCH_BUDGET'
|
|
245
|
+
log('numeric_budget_skipped', retained=selected['id'])
|
|
246
|
+
except SearchBudgetExhausted as budget_error:
|
|
247
|
+
self._budget_stopped('NUMERIC', attempt['best_verified_anchor'], attempt, log, budget_error)
|
|
248
|
+
selected = copy.deepcopy(attempt['best_verified_anchor'])
|
|
249
|
+
tuning_status = 'OPTUNA_STOPPED_SEARCH_BUDGET'
|
|
250
|
+
log('numeric_search_stopped', retained=selected['id'], reason=tuning_status)
|
|
251
|
+
self._finish_search_if_public('SEARCH_COMPLETE')
|
|
252
|
+
check()
|
|
253
|
+
prediction = verify(selected, selection)
|
|
254
|
+
primary = risk(task, sy, prediction, list(range(len(classes))))
|
|
255
|
+
if risk(task, sy, pure_prediction, list(range(len(classes)))) < primary:
|
|
256
|
+
raise ValueError('Lost verified untuned anchor')
|
|
257
|
+
|
|
258
|
+
def recipe(p):
|
|
259
|
+
return {'schema': 'morph026-frozen-form-v1', 'task': task, 'family': p['family'], 'structure': copy.deepcopy(p['recipe']), 'params': copy.deepcopy(p['params']), 'seed': seed, 'training_identity': copy.deepcopy(identity), 'preprocessing': encoder.to_dict(), 'mutations': []}
|
|
260
|
+
mock = 'MOCK' in executor.evidence_level
|
|
261
|
+
report = {'schema': 'morph027-research-report-v1', 'task': task, 'metric': metric, 'classes': classes, 'seed': seed, 'best_family': selected['family'], 'SEARCH_primary': primary, 'selection': 'BEST_VERIFIED_SEARCH_NOT_GENERALIZATION_GUARANTEE', 'families': {'evaluated': [packets[n]['family'] for n in completed if n in families], 'not_evaluated': [f for f in ['boost', 'bag'] if f not in [packets[n]['family'] for n in completed if n in families]], 'exclusion_reason': 'USER_FAMILY_LIMIT_OR_SEARCH_BUDGET'}, 'tuning': tuning_status, 'trials': trials, 'trial_evidence': 'MOCK_DRIVER_NOT_REAL_TRIALS' if mock else 'EXECUTOR_BOUND_NUMERIC_CALLBACKS', 'morphing': morph, 'stop_reason': stop_reason(event='planned'), 'stop_details': {'family': 'FINITE_PREDECLARED_CANDIDATES_COMPLETE_NOT_STALL', 'structural': stop_reason(event='no_actions') if self.morphing == 'auto' else 'DISABLED', 'numeric': 'PLANNED_TRIALS_COMPLETE' if trial_cap else tuning_status, 'global_optimum_claim': False}, 'budget': {'seconds': 150.0 if self.time_budget == 'auto' else self.time_budget, 'processes': 1, 'n_jobs': 1, 'max_family_requests': len(families) + trial_cap + self._extra_opportunities(), 'max_numeric_callbacks': trial_cap, 'model_bytes': 32 * 1024 ** 2, 'expanded_cells': 2000000, 'peak_RAM_limit_qualified': False, 'external_v2_learning_admission_required': True}, 'accounting': {k: attempt[k] for k in ('logical_family_requests', 'numeric_callback_requests', 'physical_fits')}, 'worker_admission': executor.evidence_level, 'events': events, 'refit_performed': False, 'GUARD_used': False, 'final_model_role': 'TRAIN_FITTED_SEARCH_SELECTED', 'wall_seconds': time.monotonic() - start, 'process_cpu_seconds': time.process_time() - cpu, 'descendant_cpu': 'UNKNOWN', 'peak_RSS': 'UNKNOWN', 'cost_scope': 'OPERATIONAL_ONLY_NOT_PERFORMANCE', 'stop_recovery': 'ERROR_OR_STOP_LEAVES_PRIOR_FITTED_OBJECT_UNCHANGED', 'limitations': ['Research import only', 'No new native E2E evidence from software replay', 'No admitted automatic mutation or OOF', 'No independent utility/performance/platform/sklearn qualification', 'No retrainable exported procedure']}
|
|
262
|
+
variants = {'pure': {'model': models[pure['id']], 'recipe': recipe(pure), 'origin': 'PRE_FINAL_NUMERIC_SEARCH', 'exportable': not mock, 'evidence': executor.evidence_level, 'SEARCH_primary': risk(task, sy, pure_prediction, list(range(len(classes))))}}
|
|
263
|
+
chosen = 'pure'
|
|
264
|
+
if trial_cap:
|
|
265
|
+
variants['tuned'] = {'model': models[selected['id']], 'recipe': recipe(selected), 'origin': 'POST_FINAL_NUMERIC_SEARCH', 'exportable': not mock, 'evidence': executor.evidence_level, 'SEARCH_primary': primary}
|
|
266
|
+
chosen = 'tuned'
|
|
267
|
+
learned = {'model_': models[selected['id']], 'encoder_': encoder, 'task_': task, 'n_features_in_': len(rows[0]), 'best_family_': selected['family'], 'best_recipe_': recipe(selected), 'best_params_': copy.deepcopy(selected['params']), 'structure_': copy.deepcopy(selected['recipe']), 'stop_reason_': report['stop_reason'], 'report_': report, '_variants': variants, '_selected_variant': chosen}
|
|
268
|
+
if task != 'regression':
|
|
269
|
+
learned['classes_'] = tuple(classes)
|
|
270
|
+
if names is not None:
|
|
271
|
+
learned['feature_names_in_'] = tuple(names)
|
|
272
|
+
for k in list(self.__dict__):
|
|
273
|
+
if k.endswith('_') and k != 'last_attempt_' or k in ('_variants', '_selected_variant', '_untuned_model', '_untuned_recipe'):
|
|
274
|
+
del self.__dict__[k]
|
|
275
|
+
self.__dict__.update(learned)
|
|
276
|
+
attempt.update(status='PASS', stop_reason=report['stop_reason'])
|
|
277
|
+
return self
|
|
278
|
+
except BaseException as exc:
|
|
279
|
+
event = 'timeout' if isinstance(exc, TimeoutError) else 'stop' if isinstance(exc, StopRequested) else 'budget' if isinstance(exc, BudgetExhausted) else 'not_admitted' if isinstance(exc, TrainingNotAdmitted) else 'error'
|
|
280
|
+
attempt.update(status='BLOCKED' if event == 'not_admitted' else 'STOP' if event in ('timeout', 'stop', 'budget') else 'FAIL', stop_reason=stop_reason(event=event), error=type(exc).__name__, message=str(exc))
|
|
281
|
+
raise
|
|
282
|
+
|
|
283
|
+
def _diagnose(self, context):
|
|
284
|
+
if context != {'OOF': None, 'admitted_operators': []}:
|
|
285
|
+
raise ValueError('No trained diagnostic producer admitted; GUARD and caller-provided evidence forbidden')
|
|
286
|
+
return mutation_admission(self.morphing)
|
|
287
|
+
|
|
288
|
+
def report(self):
|
|
289
|
+
value = super().report()
|
|
290
|
+
value['variants'] = self.available_variants()
|
|
291
|
+
return value
|
|
292
|
+
|
|
293
|
+
def _evaluate_mutation(self, proposal):
|
|
294
|
+
raise TrainingNotAdmitted('No default structural operator or mutation budget admitted')
|
|
295
|
+
|
|
296
|
+
def available_variants(self):
|
|
297
|
+
self._fitted()
|
|
298
|
+
return {k: {'origin': v['origin'], 'params': copy.deepcopy(v['recipe']['params']), 'exportable': v['exportable'], 'evidence': v['evidence'], 'SEARCH_primary': v.get('SEARCH_primary')} for k, v in self._variants.items()}
|
|
299
|
+
|
|
300
|
+
def _variant(self, name):
|
|
301
|
+
self._fitted()
|
|
302
|
+
name = self._selected_variant if name == 'selected' else name
|
|
303
|
+
if name not in self._variants:
|
|
304
|
+
raise VariantUnavailable('Requested variant has no retained, verified weights; a separately budgeted fit may be needed')
|
|
305
|
+
v = self._variants[name]
|
|
306
|
+
if not v['exportable']:
|
|
307
|
+
raise VariantUnavailable('Software replay cannot be exported as a newly trained pure/tuned variant')
|
|
308
|
+
obj = Previous(**{k: v for k, v in self.get_params().items() if k != 'capacity'})
|
|
309
|
+
for k in ('encoder_', 'task_', 'n_features_in_', 'classes_', 'feature_names_in_'):
|
|
310
|
+
if hasattr(self, k):
|
|
311
|
+
setattr(obj, k, copy.deepcopy(getattr(self, k)))
|
|
312
|
+
obj.model_ = v['model']
|
|
313
|
+
obj.best_recipe_ = copy.deepcopy(v['recipe'])
|
|
314
|
+
obj.best_family_ = v['recipe']['family']
|
|
315
|
+
obj.best_params_ = copy.deepcopy(v['recipe']['params'])
|
|
316
|
+
obj.report_ = self.report()
|
|
317
|
+
obj.report_.update(exported_variant=name, SEARCH_primary=v.get('SEARCH_primary'), best_family=obj.best_family_)
|
|
318
|
+
obj.stop_reason_ = self.stop_reason_
|
|
319
|
+
return obj
|
|
320
|
+
|
|
321
|
+
def export_python(self, path, *, variant='selected'):
|
|
322
|
+
self._variant(variant).export_python(path)
|
|
323
|
+
|
|
324
|
+
def save_recipe(self, path, *, variant='selected'):
|
|
325
|
+
self._variant(variant).save_recipe(path)
|
|
326
|
+
|
|
327
|
+
def save(self, path, *, variant='all'):
|
|
328
|
+
self._fitted()
|
|
329
|
+
configure_temp()
|
|
330
|
+
names = list(self._variants) if variant == 'all' else [self._selected_variant if variant == 'selected' else variant]
|
|
331
|
+
packed = {}
|
|
332
|
+
origins = {}
|
|
333
|
+
with OwnedTemporaryDirectory() as tmp:
|
|
334
|
+
for name in names:
|
|
335
|
+
obj = self._variant(name)
|
|
336
|
+
p = artifact_path(Path(tmp) / (name + '.json'))
|
|
337
|
+
obj.save(p)
|
|
338
|
+
packed[name] = read_json(p, LoadLimits(max_bytes=32 * 1024 ** 2))
|
|
339
|
+
origins[name] = {'origin': self._variants[name]['origin'], 'evidence': self._variants[name]['evidence']}
|
|
340
|
+
body = {'schema': 'morph027-native-control-v1', 'constructor': self.get_params(), 'selected_variant': self._selected_variant if self._selected_variant in names else names[0], 'variants': packed, 'origins': origins}
|
|
341
|
+
if len(json.dumps(body, allow_nan=False).encode('utf8')) > 32 * 1024 ** 2:
|
|
342
|
+
raise ValueError('Bounded total variant payload required')
|
|
343
|
+
path = artifact_path(path)
|
|
344
|
+
if path.exists():
|
|
345
|
+
raise FileExistsError('Never overwrite research model evidence')
|
|
346
|
+
write_json(path, body)
|
|
347
|
+
|
|
348
|
+
@classmethod
|
|
349
|
+
def load(cls, path):
|
|
350
|
+
data = read_json(artifact_path(path), LoadLimits(max_bytes=32 * 1024 ** 2))
|
|
351
|
+
if set(data) != {'schema', 'constructor', 'selected_variant', 'variants', 'origins'} or data['schema'] != 'morph027-native-control-v1':
|
|
352
|
+
raise ValueError('Exact bounded private control schema required')
|
|
353
|
+
vs = data['variants']
|
|
354
|
+
origins = data['origins']
|
|
355
|
+
if type(vs) is not dict or not vs or (not set(vs) <= {'pure', 'tuned'}) or (set(origins) != set(vs)) or (data['selected_variant'] not in vs):
|
|
356
|
+
raise ValueError('Bounded named variants required')
|
|
357
|
+
obj = cls(**data['constructor'])
|
|
358
|
+
configure_temp()
|
|
359
|
+
loaded = {}
|
|
360
|
+
with OwnedTemporaryDirectory() as tmp:
|
|
361
|
+
for name, body in vs.items():
|
|
362
|
+
o = origins[name]
|
|
363
|
+
if set(o) != {'origin', 'evidence'} or o['origin'] not in ('PRE_FINAL_NUMERIC_SEARCH', 'VERIFIED_B0_UNTUNED', 'POST_FINAL_NUMERIC_SEARCH') or (not isinstance(o['evidence'], str)) or ('MOCK' in o['evidence']):
|
|
364
|
+
raise ValueError('Explicit genuine variant provenance required')
|
|
365
|
+
if name == 'pure' and o['origin'] == 'POST_FINAL_NUMERIC_SEARCH' or (name == 'tuned' and o['origin'] != 'POST_FINAL_NUMERIC_SEARCH'):
|
|
366
|
+
raise ValueError('Never relabel tuned weights as pure')
|
|
367
|
+
p = artifact_path(Path(tmp) / (name + '.json'))
|
|
368
|
+
write_json(p, body)
|
|
369
|
+
v = Previous.load(p)
|
|
370
|
+
if v.task_ != body['recipe']['task']:
|
|
371
|
+
raise ValueError('Changed task')
|
|
372
|
+
expected = HyperParams(**v.best_params_)
|
|
373
|
+
for m in v.model_.components:
|
|
374
|
+
actual = asdict(m.params_)
|
|
375
|
+
want = asdict(expected if v.best_family_ == 'boost' else replace(expected, n_estimators=1, learning_rate=1.0, row_fraction=1.0))
|
|
376
|
+
if actual != want:
|
|
377
|
+
raise ValueError('Recipe parameters do not describe the actual weights')
|
|
378
|
+
if name == 'tuned' and (not v.report_.get('trials') or v.report_.get('trial_evidence') not in ('EXECUTOR_BOUND_NUMERIC_CALLBACKS', 'AUTHENTICATED_HISTORICAL_REAL_TPE4')):
|
|
379
|
+
raise ValueError('No executed numeric trajectory for tuned variant')
|
|
380
|
+
loaded[name] = v
|
|
381
|
+
v = loaded[data['selected_variant']]
|
|
382
|
+
for other in loaded.values():
|
|
383
|
+
if (other.task_, other.classes_ if hasattr(other, 'classes_') else (), other.best_recipe_['structure'], other.best_recipe_['training_identity']) != (v.task_, v.classes_ if hasattr(v, 'classes_') else (), v.best_recipe_['structure'], v.best_recipe_['training_identity']):
|
|
384
|
+
raise ValueError('Variants must share the same frozen structure/data/map')
|
|
385
|
+
for k in ('model_', 'encoder_', 'task_', 'n_features_in_', 'classes_', 'feature_names_in_', 'best_family_', 'best_recipe_', 'best_params_', 'stop_reason_', 'report_'):
|
|
386
|
+
if hasattr(v, k):
|
|
387
|
+
setattr(obj, k, getattr(v, k))
|
|
388
|
+
obj.structure_ = copy.deepcopy(v.best_recipe_['structure'])
|
|
389
|
+
obj._selected_variant = data['selected_variant']
|
|
390
|
+
obj._variants = {k: {'model': v.model_, 'recipe': copy.deepcopy(v.best_recipe_), **origins[k], 'exportable': True, 'SEARCH_primary': v.report_.get('SEARCH_primary')} for k, v in loaded.items()}
|
|
391
|
+
return obj
|
|
392
|
+
|
|
393
|
+
def export_bundle(self, directory, *, variants=('pure',)):
|
|
394
|
+
if type(variants) is not tuple or not variants or len(set(variants)) != len(variants):
|
|
395
|
+
raise ValueError('Distinct variant tuple required')
|
|
396
|
+
for name in variants:
|
|
397
|
+
self._variant(name)
|
|
398
|
+
directory = artifact_path(directory)
|
|
399
|
+
if directory.exists():
|
|
400
|
+
raise FileExistsError('New export directory required')
|
|
401
|
+
directory.mkdir(parents=True)
|
|
402
|
+
out = []
|
|
403
|
+
for name in variants:
|
|
404
|
+
p = directory / (name + '.json')
|
|
405
|
+
self.save(p, variant=name)
|
|
406
|
+
out.append(reference(p))
|
|
407
|
+
p = directory / (name + '-recipe.json')
|
|
408
|
+
self.save_recipe(p, variant=name)
|
|
409
|
+
out.append(reference(p))
|
|
410
|
+
p = directory / (name + '-predictor.py')
|
|
411
|
+
self.export_python(p, variant=name)
|
|
412
|
+
out.append(reference(p))
|
|
413
|
+
p = directory / 'EXPORT.json'
|
|
414
|
+
write_json(p, {'schema': 'morph027-inference-export-v1', 'status': 'COMPLETE', 'artifacts': out, 'retraining_procedure': 'NOT_SUPPORTED', 'new_fits': 0, 'report': self.report()})
|
|
415
|
+
return reference(p)
|
|
416
|
+
|
|
417
|
+
def export_retrainable(self, path):
|
|
418
|
+
raise NotImplementedError('Only inference standalone and declarative recipe are qualified; generic retraining admission is missing')
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Linux_wheel_audit": {
|
|
3
|
+
"extra_shared_libraries_bundled": 0,
|
|
4
|
+
"native_ELF_changed": false,
|
|
5
|
+
"requested_platform": "manylinux_2_17_x86_64",
|
|
6
|
+
"tool": "auditwheel6.8.2",
|
|
7
|
+
"versioned_symbols": [
|
|
8
|
+
"GLIBC_2.2.5"
|
|
9
|
+
],
|
|
10
|
+
"whole_pipeline_on_older_glibc_tested": false
|
|
11
|
+
},
|
|
12
|
+
"backend": "automatic-native",
|
|
13
|
+
"capacity_profile": {
|
|
14
|
+
"default_estimators": 2,
|
|
15
|
+
"explicit_verified_estimators": 8,
|
|
16
|
+
"independent_real_test_confirmed": false,
|
|
17
|
+
"new_default_adopted": false
|
|
18
|
+
},
|
|
19
|
+
"files": {
|
|
20
|
+
"__init__.py": "a3d4e3364b56f0a2f952a81113f8bc3159f7b5a44d285300ccb6a2dcccd53cb7",
|
|
21
|
+
"__main__.py": "935a1c1166b0c1ea35a82256345000bf2c73ded718d77773bc27a71ecce28f7d",
|
|
22
|
+
"_experimental/__init__.py": "af368cce8e8a71327fdf5a8b61c81d6d6fdef62f924800408d7f2b2ca1d82e52",
|
|
23
|
+
"_experimental/admission.py": "7afaad7937655739b9e6c4f469d337c9ecaeeecbfbe4f435f669d07e8af5022c",
|
|
24
|
+
"_experimental/base.py": "3b24242af5bdde79eeba086354f23446cbf911f570c0b63246d491abd74316e5",
|
|
25
|
+
"_experimental/component_cache_v2.py": "8bcdf575213ed71a68fbc79cc86e58d2007e1539dd0e5e22ca80273696c3b78f",
|
|
26
|
+
"_experimental/evolution_report.py": "0496feeb84cfdde473679713a9432caa581a017db3dfb114fd30da6296bab642",
|
|
27
|
+
"_experimental/execution_v2.py": "596318d9e55faf9b94ba8430fd78b6152750d299c9ac7778769efd7e4e838c58",
|
|
28
|
+
"_experimental/facade.py": "0408181efdb8139470a8356a48231bdf357c06c0358c835c89729e8f2833e884",
|
|
29
|
+
"_experimental/integrated.py": "ccaa9ac5441897492d55ce94b47ead55338274ae1b9127ef9a78e23711311e37",
|
|
30
|
+
"_experimental/learning.py": "e2e7b68cc27a94451bcc4efa57f9c78d0b8dc3104088a26007a112c255e505c6",
|
|
31
|
+
"_experimental/numeric_fixture.py": "f05fb8cb1757ebb841863f3a32eb331999bd4c4fc2a51bc1f11cc8a52d6508d9",
|
|
32
|
+
"_experimental/parameter_contract.py": "261ee3edece961d78ec0bccc0c5c7edc77d0797620d93f916b8fb96bff81fea6",
|
|
33
|
+
"_experimental/postfit.py": "493ee24a0c8f5eb6374bf0afbf1f1c083de7d96e9750cad4c7fdc1c759d8d9f4",
|
|
34
|
+
"_experimental/preprocessing.py": "1136e69d814124a90e999a9f5701fdbda716ab623998529ea042c8fb35c1e682",
|
|
35
|
+
"_experimental/processes.py": "577394affa54f66c0bf0bc55ce1619b0e10a7e4f3177c1af0256196f7347e6b7",
|
|
36
|
+
"_experimental/producer.py": "07d07410b8e85efbe9e38ed4761f4495f5e909b3f56f8ff1b52abb639e3afebf",
|
|
37
|
+
"_experimental/product.py": "568b02f61e5f772ab165b72ccf37217c6e48a9d5455480cd1ecbf236893002c4",
|
|
38
|
+
"_experimental/product_cli.py": "2fdfddfc573a5f5fee5ebd14bdd8aca3e5fbe7e746f169c47347fa9da0247509",
|
|
39
|
+
"_experimental/roundtrip_v3.py": "fb2999bee513f40e076543323da81385d1ceb7cf68850054f921b3c2c2a37d39",
|
|
40
|
+
"_experimental/runtime_io.py": "605c37ccf425d48de4ed52456b58414c4577b2018d2932e1aa7e7d30fa06e29c",
|
|
41
|
+
"_experimental/sampling.py": "a4aeb4536f5cf8280f4166ba7051ca2fb76aad8619958114a799b89afa773975",
|
|
42
|
+
"_experimental/support.py": "e6108af84a75a39813a3a665d266a913e104168c8a3cfc334cd6293e07101cfc",
|
|
43
|
+
"_experimental/target.py": "d2da94f69f7a4cf59b8d62bec69cd82f6a8f300827553900e6cba587ce7f1f9c",
|
|
44
|
+
"_experimental/training.py": "af9e2cc7ebfc7418cad90c3133993990b196fe94be1670f988f0cd8e3cfb70d3",
|
|
45
|
+
"_experimental/worker.py": "acb03be1dfaef5aac0ebfc5e050d90184d2154e74206fe0fb6c445e705608fc3",
|
|
46
|
+
"_installed.py": "1346e28b929f4103b2203192fcb9a6949320e232927bc312843390df8e9efcfd",
|
|
47
|
+
"_native/__init__.py": "f7f1f59f08aba5c94c66779ff4ebeca960675e3350a7fe9613f64dc65c6cea67",
|
|
48
|
+
"_native/bin/win_amd64/morphtree_kernels.dll": "1c577f636a74d873942d31ab81a1278eda8096252531c52520d00db2471d2a14",
|
|
49
|
+
"_native/buffers.py": "f51313cf910123eb1729e9f73270f15548691d2be7f9dae5479572828d3541c5",
|
|
50
|
+
"_native/loader.py": "a099872a1e7341075f9526cc75840bd38aa2908d8999310e885d1859a17068cb",
|
|
51
|
+
"_native/manifest.json": "0e5ba02d5a565b1fa424b1c1c5fac891bb7082e535d2dceeae65c36df2eec4f3",
|
|
52
|
+
"_native/runtime.py": "304c82cd811c769a74148580ffcbe4b15e5ffd28ae6fbef1e74af4f2aee8123e",
|
|
53
|
+
"_native/src/histogram.c": "4b05c05dab1de35c2b8c7cee69cf743b51f746e1d0a14b782df73d3ce959bf39",
|
|
54
|
+
"_native/src/traversal.c": "487d8ca46c96faded18d99dcda0abcb3c8a0fa783070a7da23dd5692a7a69406",
|
|
55
|
+
"api.py": "3c333b859bc43bedd8067ae9e6ad297d755a43dc289890c14f876a175301abb9",
|
|
56
|
+
"api_compat.py": "ba72b57232bda81e0f6392119f662e2e6d1fec9e7fc3571bb0e9ef10e4d89a8b",
|
|
57
|
+
"backend.py": "881d6025e72cd5675cd6da7b5b2e950d6ade97d63a25735321e5a739c27ef26c",
|
|
58
|
+
"booster.py": "92040ddb5ec9dec32dc14c3dbb160398ac764f440e3018bff5e99cf374ad066e",
|
|
59
|
+
"cli.py": "e8b9c79e67e876716b22f1ce86142b24d789d15ec3115d1ad9505d25e08f21f3",
|
|
60
|
+
"config.py": "d47be3b353ebcd619fb2844beb1e9e5f0b6dea5ff642c579a10c127d57af7ac1",
|
|
61
|
+
"control.py": "2f1c20f9fdaf426ed02500404874445895a022fa2a00fda65e3f195e651ee3cd",
|
|
62
|
+
"data.py": "3123850c2f2b8bfa1c7d599697c8cf5f02c162f30f2691d018600d6231cc0451",
|
|
63
|
+
"diagnostics.py": "4bef87e037d16e58cb03d4d129ebd42db9eac880342c520aef073daca687adbc",
|
|
64
|
+
"estimators.py": "d387432935d564a357ffa3ea1b6b804583c2d135b93310528273dc1221aff58b",
|
|
65
|
+
"examples.py": "5b1deccceb772346e3fd5f6d2a9756477d99e458713fa015f125f4d7bef2a635",
|
|
66
|
+
"exporting.py": "161bebaee9728da105446e937b14ff50dcbefcd6a3ef63b197f357dcf24917f8",
|
|
67
|
+
"legacy_artifacts.py": "cd70250ffacb20085e32c31f29e4b728caa06ea1cf8ec060b4e455b889e5b309",
|
|
68
|
+
"metrics.py": "785f2a7d2c0338aca950107699721adea15d61fa7a6b103e471c99b308b4d6c5",
|
|
69
|
+
"model.py": "389ad29547ddd5eaca0bfdc325627f91f9d4b4734ac44d9aa69296918678dd38",
|
|
70
|
+
"mutations.py": "4d98f5d9a9b4f786d8d640f478356a3a034a78740a286ea2a0b121cd7a647cb5",
|
|
71
|
+
"native_lab_backend.py": "871774e0fc08ae448b60725f122df437ba6cf188eb8a3f7681a12bae972c52b5",
|
|
72
|
+
"numpy_backend.py": "71669be1bf84a96dfcc63fc5b89ecc0f9cf03463313953e573c0d162ccd48152",
|
|
73
|
+
"optuna_tuner.py": "969ee92fed53955b12de903034caff324714cdcdc1347591dd8d0d1250aa9d90",
|
|
74
|
+
"persistence.py": "e4c52f6c4dbc227adfa39e362ce5274306d7f320eb4b68f3a3f41a92d1446436",
|
|
75
|
+
"prediction_output.py": "f36e550b898fb9225b82c0ba0799daa517129debd09b10f346018b8c6d33d964",
|
|
76
|
+
"prepared_bins.py": "178f9c73744dcaeb6e91943deb23e8f410ef85ec97743f8802f4c3317622abbf",
|
|
77
|
+
"public.py": "775ef54dd1576f4f0bba15162cd3547e086a9245be4d9cc50c0af0f4a1c3b9db",
|
|
78
|
+
"resource_plan.py": "bebb6a781627cc1a3494a35747df7f4ffe1350480cf3ec0eb752b92e3558c5b2",
|
|
79
|
+
"scalable.py": "bed96c724ca3be9c10973f307b98eae3fb33866abc5b38fb72ca2e406b03333d",
|
|
80
|
+
"scalable_backend.py": "04221e17b552cc30ce600857be62785f55c4e7958b5b90728ceeb20c075effcc",
|
|
81
|
+
"scalable_checkpoint.py": "24fd03a2f41e5b157b7e1cbd53f2fa0a94977f3d3ee0affd63a3ff9af07212af",
|
|
82
|
+
"scalable_data.py": "e9a85f44cae2736594b5c76d37fcd36d40f47211b5f7ade9b7a0e62d22de1885",
|
|
83
|
+
"scalable_receipts.py": "15090c5d9019f21b2f04dbec9a5266a8bf7eb26d4f34320b47ed79cd05530f0d",
|
|
84
|
+
"scalable_target.py": "7ac25a34f753109756fda9a0e7d80ec57f4dd0186761c1c2ea16fe6760c4de06",
|
|
85
|
+
"scalable_variants.py": "c35cf11448f3c9f0d58a3fb1c0188c22ba83ccc4e1f0fb4c1527f9488acd75ff",
|
|
86
|
+
"sklearn_view.py": "5f5aebaca51ff78596ce842cb0d3b500365d42cf087954120fcaa8a6025260e8",
|
|
87
|
+
"source_markers.py": "0d44fe9364cb4902c16ee0d480dc2a5b843ddaa0ce179791b2d746e158ae6ddd",
|
|
88
|
+
"species.py": "2b8669426374cdee1eac5c14eac7f7c42b9438c70fc3b0a3af9e191bb40992bf",
|
|
89
|
+
"temporary.py": "29fc30a9644508d8d5f1f5254eb48e590b48f585947655952424f984edeead15",
|
|
90
|
+
"training_fragment.py": "3fbe4f25ca3fc3c23a781b2c1a955bb2e05b84f29c422ff92512b003e573848e",
|
|
91
|
+
"tree.py": "875f93a47b005ad362be77730af6bdb0cd82c39e369ffc525913aab2a2c1f4a5",
|
|
92
|
+
"tuning.py": "0765b39a34d5825028bb91c6c6af2b68a51164c622895d735722096597e60b66"
|
|
93
|
+
},
|
|
94
|
+
"historical_provenance": {
|
|
95
|
+
"frozen_engine_manifest_sha256": "cd090c6739f9ca4a6463616cff05383d6a200f76e41b50248713f8bb7b077685",
|
|
96
|
+
"learning_mathematics_changed": false,
|
|
97
|
+
"original_python_reference_version": "2.1.0",
|
|
98
|
+
"previous_native_reference_version": "2.1.0"
|
|
99
|
+
},
|
|
100
|
+
"native_lab": {
|
|
101
|
+
"default_backend": "Verified C histograms and cached traversal; equivalent Python traversal below 128 rows",
|
|
102
|
+
"evidence_campaigns": [
|
|
103
|
+
"VERSION121",
|
|
104
|
+
"VERSION122"
|
|
105
|
+
],
|
|
106
|
+
"fresh_RC_profiles": [
|
|
107
|
+
"WindowsPython3.12.10",
|
|
108
|
+
"Ubuntu24.04WSL2Python3.12.3"
|
|
109
|
+
],
|
|
110
|
+
"historical_evidence_campaigns": [
|
|
111
|
+
"RC116",
|
|
112
|
+
"RC117"
|
|
113
|
+
],
|
|
114
|
+
"historical_training_distribution_version": "3.0.0rc1",
|
|
115
|
+
"public_release": false,
|
|
116
|
+
"publication_approved": false,
|
|
117
|
+
"qualification_labels_only_successor": true,
|
|
118
|
+
"qualification_scope": "Fresh2.1.0 full installed pipelines VERSION121Windows312 andVERSION122UbuntuWSL2312;3.13/3.14 retained source-lineage training plus fresh installed/inference checks;other platforms not claimed",
|
|
119
|
+
"qualified_profiles": [
|
|
120
|
+
{
|
|
121
|
+
"features": 7,
|
|
122
|
+
"os": "Windows 11 build 26300 x64",
|
|
123
|
+
"python": [
|
|
124
|
+
"3.12.10",
|
|
125
|
+
"3.13.17",
|
|
126
|
+
"3.14.9"
|
|
127
|
+
],
|
|
128
|
+
"rows": 25003,
|
|
129
|
+
"tasks": [
|
|
130
|
+
"binary",
|
|
131
|
+
"multiclass",
|
|
132
|
+
"regression"
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"features": 7,
|
|
137
|
+
"os": "Ubuntu 24.04.4 WSL2 x86_64 glibc 2.39",
|
|
138
|
+
"python": [
|
|
139
|
+
"3.12.3",
|
|
140
|
+
"3.13.17",
|
|
141
|
+
"3.14.9"
|
|
142
|
+
],
|
|
143
|
+
"rows": 25003,
|
|
144
|
+
"tasks": [
|
|
145
|
+
"binary",
|
|
146
|
+
"multiclass",
|
|
147
|
+
"regression"
|
|
148
|
+
]
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"features": 15,
|
|
152
|
+
"os": "Windows 11 build 26300 x64",
|
|
153
|
+
"python": [
|
|
154
|
+
"3.12.10"
|
|
155
|
+
],
|
|
156
|
+
"rows": [
|
|
157
|
+
10003,
|
|
158
|
+
200003
|
|
159
|
+
],
|
|
160
|
+
"tasks": [
|
|
161
|
+
"binary",
|
|
162
|
+
"multiclass",
|
|
163
|
+
"regression"
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
],
|
|
167
|
+
"training_distribution_version": "2.1.0",
|
|
168
|
+
"unqualified": [
|
|
169
|
+
"Linux small/large training",
|
|
170
|
+
"million-row training",
|
|
171
|
+
"Python 3.15 ordinary install",
|
|
172
|
+
"authentic macOS",
|
|
173
|
+
"other Linux distributions full pipeline",
|
|
174
|
+
"hosted Kaggle"
|
|
175
|
+
],
|
|
176
|
+
"version_approved": true,
|
|
177
|
+
"whole_pipeline_native_qualified": true
|
|
178
|
+
},
|
|
179
|
+
"prediction_output_contract": {
|
|
180
|
+
"class_order": "classes_",
|
|
181
|
+
"default_standalone": "stdlib Python lists",
|
|
182
|
+
"new_training": false,
|
|
183
|
+
"numeric_values_changed": false,
|
|
184
|
+
"numpy_standalone": "output_format='numpy'",
|
|
185
|
+
"predict": "numpy.ndarray(n_samples,)",
|
|
186
|
+
"predict_proba": "numpy.float64(n_samples,n_classes)"
|
|
187
|
+
},
|
|
188
|
+
"private_research": false,
|
|
189
|
+
"public_description": {
|
|
190
|
+
"README_modified_by_agent": true,
|
|
191
|
+
"README_sha256": "0c567465e0db8cf91112fef749f83f31d78e5aa48f7088817a3617c91154d9f4",
|
|
192
|
+
"authorization_sha256": "da902c3c4bc4ca321a2e94e5e4513dc1f714935fa17c1d602c9e08e2d059f0b3",
|
|
193
|
+
"content_type": "text/markdown",
|
|
194
|
+
"normalized_description_sha256": "0c567465e0db8cf91112fef749f83f31d78e5aa48f7088817a3617c91154d9f4",
|
|
195
|
+
"source": "README.md",
|
|
196
|
+
"source_owner_review_pending": true,
|
|
197
|
+
"source_revision_authorization": "EXPLICIT_OWNER_DIRECTIVE"
|
|
198
|
+
},
|
|
199
|
+
"schema": "morph030-installed-payload-v1",
|
|
200
|
+
"scientific_training_authority": 0,
|
|
201
|
+
"scope": "LOCAL_RC_WITH_RETAINED_QUALIFIED_ENGINE",
|
|
202
|
+
"version": "2.1.0",
|
|
203
|
+
"workspace_sources_required": false
|
|
204
|
+
}
|