tracebloc 1.2.78__tar.gz → 1.2.80__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.
- {tracebloc-1.2.78 → tracebloc-1.2.80}/PKG-INFO +1 -1
- {tracebloc-1.2.78 → tracebloc-1.2.80}/pyproject.toml +1 -1
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/families/hf/__init__.py +3 -2
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/families/hf/_build.py +24 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/families/tabular.py +34 -34
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/outputs.py +1 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc.egg-info/PKG-INFO +1 -1
- {tracebloc-1.2.78 → tracebloc-1.2.80}/MANIFEST.in +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/README.md +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/license.txt +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/setup.cfg +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/__init__.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/_deprecation.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/_framework_utils.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/_http_utils.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/_link_answer.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/_link_regeneration.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/_linking.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/_raw_width_note.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/_stored_link.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/_upload_conversion.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/checks.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/client.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/config.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/contracts/stage_urls.v1.json +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/contracts/stage_urls.v1.source.json +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/contracts/survival_payload.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/contracts/training_requirements.source.json +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/contracts/training_requirements.txt +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/__init__.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/acceptance.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/families/__init__.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/families/hf/_model_type.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/families/vision/__init__.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/families/vision/_matching.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/gate.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/heads.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/interfaces.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/licence/__init__.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/licence/spdx.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/owncode/__init__.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/owncode/arguments.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/owncode/assemble.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/owncode/checkpoint.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/owncode/gate_rules.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/owncode/generate.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/owncode/head.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/owncode/import_check.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/owncode/layer0.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/owncode/live.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/owncode/model_class.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/owncode/remote.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/owncode/repo.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/owncode/shake.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/owncode/source_tree.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/package.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/report.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/tokenizers.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/convert/training_versions.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/env_login.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/exceptions.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/fetch.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/inference.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/library_fetch.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/lifelines_weights.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/link_model_dataset.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/notebook/__init__.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/notebook/templates/_partials.tpl +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/notebook/templates/embeddings.tpl +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/notebook/templates/nlp_finetune.tpl +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/notebook/templates/nlp_generative.tpl +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/notebook/templates/survival.tpl +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/notebook/templates/tabular_timeseries.tpl +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/notebook/templates/vision_from_scratch.tpl +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/raw_mode.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/raw_mode_frame.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/raw_mode_seed.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/raw_mode_survival.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/raw_mode_torch.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/seed_weights.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/training/__init__.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/training/augmentation.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/training/callbacks.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/training/converted.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/training/features.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/training/image_size.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/training/lora.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/training/lora_validation.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/training/loss.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/training/memory_estimate.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/training/plan.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/training/preprocessing.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/training/shape.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/training/subdataset.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/training/submitter.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/training/summary.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/__init__.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/lifelines_time_to_event.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/model_upload.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/scikit_survival_time_to_event.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/sequence_length.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/skl_tabular_base.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/skl_tabular_classifier.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/skl_tabular_regression.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/statistical_base.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/survival_base.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/torch_causal_language_modeler.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/torch_embeddings.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/torch_image_classifier.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/torch_key_point_detector.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/torch_masked_language_modeler.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/torch_nlp_base.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/torch_object_detector.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/torch_semantic_segmentation.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/torch_sentence_pair_classifier.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/torch_seq2seq_modeler.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/torch_tabular_classifier.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/torch_tabular_regression.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/torch_text_classifier.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/torch_time_series_classifier.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/torch_time_series_forecaster.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/torch_time_to_event.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/torch_token_classifier.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/weight_loaders.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/upload/weights_parts.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/user.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/utils/__init__.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/utils/class_order.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/utils/constants.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/utils/custom_loss_probe.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/utils/detection_utils.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/utils/entry_point.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/utils/feature_dict.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/utils/general_utils.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/utils/key_point_detection_utils.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/utils/registry.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/utils/safetensors_io.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/utils/semantic_segmentation_utils.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/utils/tabular_classification_utils.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/utils/tabular_custom_loss_utils.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/utils/tabular_regression_utils.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/utils/text_classification_utils.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/utils/time_series_utils.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/utils/time_to_event_utils.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/utils/warnings_once.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/validation/__init__.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/validation/checker.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/validation/header_rules.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/validation/lifelines_checks.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/validation/pytorch_checks.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/validation/rewriter.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/validation/scikit_survival_checks.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc/validation/sklearn_checks.py +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc.egg-info/SOURCES.txt +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc.egg-info/dependency_links.txt +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc.egg-info/requires.txt +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc.egg-info/top_level.txt +0 -0
- {tracebloc-1.2.78 → tracebloc-1.2.80}/tracebloc_package/__init__.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tracebloc"
|
|
7
|
-
version = "1.2.
|
|
7
|
+
version = "1.2.80"
|
|
8
8
|
description = "Build AI with anyone. On data that can't move. SDK for the tracebloc collaborative AI workspace."
|
|
9
9
|
license = "MIT"
|
|
10
10
|
license-files = ["license.txt"]
|
|
@@ -24,7 +24,7 @@ from pathlib import Path
|
|
|
24
24
|
from typing import Any, Mapping
|
|
25
25
|
|
|
26
26
|
from tracebloc.convert.families.hf._build import head_prefixes, load, model_source
|
|
27
|
-
from tracebloc.convert.families.hf._build import write_weights
|
|
27
|
+
from tracebloc.convert.families.hf._build import with_pad_token_id, write_weights
|
|
28
28
|
from tracebloc.convert.families.hf._model_type import _AUTO, CONFIG_FILE, _mapping
|
|
29
29
|
from tracebloc.convert.families.hf._model_type import _names, model_type_of
|
|
30
30
|
from tracebloc.convert.families.vision import read_normalisation
|
|
@@ -454,7 +454,8 @@ class HuggingFaceFamily:
|
|
|
454
454
|
pooling = state["pooling"]
|
|
455
455
|
if pooling and pooling != ("mean",):
|
|
456
456
|
notes.append(f"declares {', '.join(pooling)} pooling; training mean-pools")
|
|
457
|
-
|
|
457
|
+
config = with_pad_token_id(state["config"], model, tokenizer)
|
|
458
|
+
source = model_source(auto_class, config, classes is not None, wrapper)
|
|
458
459
|
return GeneratedPackage(
|
|
459
460
|
family=self.name,
|
|
460
461
|
files=(GeneratedFile(f"{stem}.py", source),),
|
|
@@ -202,6 +202,30 @@ def write_weights(model: Any, wrapper: str | None, target: Path) -> tuple[str, .
|
|
|
202
202
|
return tuple(out)
|
|
203
203
|
|
|
204
204
|
|
|
205
|
+
def with_pad_token_id(
|
|
206
|
+
config: Mapping[str, Any], model: Any, tokenizer: Path | None
|
|
207
|
+
) -> Mapping[str, Any]:
|
|
208
|
+
"""``config`` with the tokenizer's pad id, when the task class reads
|
|
209
|
+
``config.pad_token_id`` and the checkpoint set none.
|
|
210
|
+
|
|
211
|
+
A decoder classifier with no pad id raises on any batch over 1.
|
|
212
|
+
"""
|
|
213
|
+
import inspect
|
|
214
|
+
|
|
215
|
+
if config.get("pad_token_id") is not None or tokenizer is None:
|
|
216
|
+
return config
|
|
217
|
+
try:
|
|
218
|
+
reads = "pad_token_id" in inspect.getsource(type(model).forward)
|
|
219
|
+
from tokenizers import Tokenizer
|
|
220
|
+
|
|
221
|
+
padding = Tokenizer.from_file(str(tokenizer)).padding
|
|
222
|
+
except (OSError, TypeError, ValueError, ImportError):
|
|
223
|
+
return config
|
|
224
|
+
if not reads or not padding or padding.get("pad_id") is None:
|
|
225
|
+
return config
|
|
226
|
+
return {**config, "pad_token_id": padding["pad_id"]}
|
|
227
|
+
|
|
228
|
+
|
|
205
229
|
def render_config(config: Mapping[str, Any]) -> str:
|
|
206
230
|
"""``CONFIG`` as a Python literal, one key per line."""
|
|
207
231
|
lines = [f" {key!r}: {value!r},\n" for key, value in config.items()]
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
"""Fitted scikit-learn, XGBoost, LightGBM, CatBoost, lifelines and scikit-survival models.
|
|
2
2
|
|
|
3
|
-
A fitted estimator or ``Pipeline
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
estimator serves the tabular task of its type (classifier, regressor or
|
|
7
|
-
survival model); the use case picks among the tasks that share that type.
|
|
8
|
-
"""
|
|
3
|
+
A fitted estimator or ``Pipeline`` becomes its framework's zoo template: ``MyModel``
|
|
4
|
+
builds the estimator from its own parameters, and the fitted model ships as the
|
|
5
|
+
weights. It serves the tabular task of its type: classifier, regressor or survival."""
|
|
9
6
|
|
|
10
7
|
from __future__ import annotations
|
|
11
8
|
|
|
@@ -26,7 +23,9 @@ from tracebloc.convert.interfaces import (
|
|
|
26
23
|
GeneratedPackage, Proof, Provenance, Recognition, RefusalCause, SourcedValue,
|
|
27
24
|
UseCaseTask, ValueSource,
|
|
28
25
|
)
|
|
26
|
+
from tracebloc._framework_utils import extra_for_module
|
|
29
27
|
from tracebloc.utils.constants import Framework, TaskCategory
|
|
28
|
+
from tracebloc.utils.general_utils import format_exception
|
|
30
29
|
|
|
31
30
|
#: The libraries whose fitted models this family reads, by top-level module.
|
|
32
31
|
FRAMEWORK_OF_ROOT = {
|
|
@@ -78,6 +77,9 @@ _FUNCTIONS = frozenset(
|
|
|
78
77
|
|
|
79
78
|
_KNOWN_ROOTS = frozenset(FRAMEWORK_OF_ROOT) | _DATA_ROOTS
|
|
80
79
|
_PICKLE_SUFFIXES = (".pkl", ".pickle", ".joblib")
|
|
80
|
+
_JOBLIB_LOCK = threading.Lock()
|
|
81
|
+
#: Each library's own error for saved model bytes its loader cannot read.
|
|
82
|
+
_LOAD_ERRORS = (("xgboost.core", "XGBoostError"), ("lightgbm.basic", "LightGBMError"), ("catboost", "CatBoostError"))
|
|
81
83
|
_FROM_MODEL = Provenance(ValueSource.MODEL, "fitted estimator", verified=True)
|
|
82
84
|
|
|
83
85
|
|
|
@@ -111,11 +113,7 @@ class _Allowlisted:
|
|
|
111
113
|
raise _UnloadableError(module, name)
|
|
112
114
|
|
|
113
115
|
|
|
114
|
-
class _Unpickler(_Allowlisted, pickle.Unpickler):
|
|
115
|
-
pass
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
_JOBLIB_LOCK = threading.Lock()
|
|
116
|
+
class _Unpickler(_Allowlisted, pickle.Unpickler): ...
|
|
119
117
|
|
|
120
118
|
|
|
121
119
|
def _load_pickled(path: Path) -> Any:
|
|
@@ -155,8 +153,21 @@ def _load(source: ConversionInput) -> Any:
|
|
|
155
153
|
f"{path.name} names {refused} in its saved state, which training does "
|
|
156
154
|
f"not load; pass the fitted model object itself instead",
|
|
157
155
|
) from None
|
|
158
|
-
except
|
|
159
|
-
|
|
156
|
+
except ModuleNotFoundError as missing:
|
|
157
|
+
if missing.name not in _KNOWN_ROOTS:
|
|
158
|
+
return None # a part of an installed library that this version lacks
|
|
159
|
+
install = f"tracebloc[{extra}]" if (extra := extra_for_module(missing.name)) else missing.name
|
|
160
|
+
message = f"{path.name} needs {missing.name}, which is not installed: pip install '{install}'"
|
|
161
|
+
raise ConversionRefusedError(RefusalCause.VERSIONS, message) from None
|
|
162
|
+
except Exception as error:
|
|
163
|
+
loaded = (getattr(sys.modules.get(m), n, None) for m, n in _LOAD_ERRORS)
|
|
164
|
+
if isinstance(error, tuple(c for c in loaded if isinstance(c, type))):
|
|
165
|
+
detail = " ".join(format_exception(error).split())[:120]
|
|
166
|
+
message = f"{path.name} holds model bytes its library cannot read ({detail})"
|
|
167
|
+
raise ConversionRefusedError(RefusalCause.NO_SOURCE, f"{message}; save it again") from None
|
|
168
|
+
if isinstance(error, (pickle.UnpicklingError, EOFError, ValueError, IndexError, ImportError, AttributeError, TypeError)):
|
|
169
|
+
return None
|
|
170
|
+
raise
|
|
160
171
|
|
|
161
172
|
|
|
162
173
|
def _root(cls: type) -> str:
|
|
@@ -214,9 +225,7 @@ def _kind(model: Any, framework: Framework) -> str | None:
|
|
|
214
225
|
return "survival"
|
|
215
226
|
from sklearn.base import is_classifier, is_regressor
|
|
216
227
|
|
|
217
|
-
if is_classifier(model)
|
|
218
|
-
return "classifier"
|
|
219
|
-
return "regressor" if is_regressor(model) else None
|
|
228
|
+
return "classifier" if is_classifier(model) else "regressor" if is_regressor(model) else None
|
|
220
229
|
|
|
221
230
|
|
|
222
231
|
def _feature_count(model: Any, framework: Framework) -> int | None:
|
|
@@ -374,11 +383,9 @@ class TabularFamily:
|
|
|
374
383
|
framework, terminal = recognition.framework, _terminal(model)
|
|
375
384
|
estimator = recognition.values["entry_point"].value
|
|
376
385
|
_check_task(estimator, framework, kind, task.category)
|
|
377
|
-
category_origin = (
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
else Provenance(ValueSource.MODEL, "estimator type")
|
|
381
|
-
)
|
|
386
|
+
category_origin = Provenance(ValueSource.DATASET, "use case", verified=True)
|
|
387
|
+
if not task.from_use_case:
|
|
388
|
+
category_origin = Provenance(ValueSource.MODEL, "estimator type")
|
|
382
389
|
header = {"framework": SourcedValue(framework, _FROM_MODEL)}
|
|
383
390
|
header["category"] = SourcedValue(task.category, category_origin)
|
|
384
391
|
header.update(_counts(recognition, task))
|
|
@@ -430,11 +437,8 @@ def _check_task(estimator: str, framework: Framework, kind: str | None, task: Ta
|
|
|
430
437
|
|
|
431
438
|
|
|
432
439
|
def _counts(recognition: Recognition, task: UseCaseTask) -> dict[str, SourcedValue]:
|
|
433
|
-
"""The counts the header needs: the model's, held to the dataset's.
|
|
434
|
-
|
|
435
|
-
A fitted model cannot take another feature or class count, so a dataset
|
|
436
|
-
that disagrees is refused; lifelines fits whatever covariates it is given.
|
|
437
|
-
"""
|
|
440
|
+
"""The counts the header needs: the model's, held to the dataset's. A fitted model
|
|
441
|
+
cannot take another count; lifelines fits whatever covariates it is given."""
|
|
438
442
|
from tracebloc.validation.header_rules import required_values
|
|
439
443
|
|
|
440
444
|
estimator = recognition.values["entry_point"].value
|
|
@@ -470,11 +474,9 @@ def _write_weights(model: Any, path: Path, notes: list[str]) -> Path | None:
|
|
|
470
474
|
try:
|
|
471
475
|
_Unpickler(io.BytesIO(data)).load()
|
|
472
476
|
except _UnloadableError as refused:
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
f"from the dataset."
|
|
477
|
-
)
|
|
477
|
+
name = type(_terminal(model)).__name__
|
|
478
|
+
notes.append(f"The fitted {name} is not shipped: its saved state names {refused}, "
|
|
479
|
+
"which training does not load. Training fits it from the dataset.")
|
|
478
480
|
return None
|
|
479
481
|
path.write_bytes(data)
|
|
480
482
|
return path
|
|
@@ -491,9 +493,7 @@ def _averaging_notes(model: Any, framework: Framework) -> list[str]:
|
|
|
491
493
|
if framework is Framework.SKLEARN:
|
|
492
494
|
from tracebloc.validation.sklearn_checks import non_averageable_estimator_reason
|
|
493
495
|
|
|
494
|
-
|
|
495
|
-
if reason:
|
|
496
|
-
notes.append(reason)
|
|
496
|
+
notes.extend(filter(None, [non_averageable_estimator_reason(model)]))
|
|
497
497
|
return notes
|
|
498
498
|
|
|
499
499
|
|
|
@@ -384,6 +384,7 @@ def torch_output_check(
|
|
|
384
384
|
return CheckFinding("output", False, detail)
|
|
385
385
|
ours, theirs = captured
|
|
386
386
|
compared = "the backbone's output"
|
|
387
|
+
probe.call(model) # the head is fresh, so only this runs it
|
|
387
388
|
except Exception as error: # noqa: BLE001 - the check reports, never raises
|
|
388
389
|
return CheckFinding(
|
|
389
390
|
"output", False, f"comparing outputs raised {_one_line(error)}"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|