tabforge-ml 2026.8.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. tabforge/__init__.py +50 -0
  2. tabforge/_metadata.py +4 -0
  3. tabforge/_vendor/__init__.py +1 -0
  4. tabforge/_vendor/tabpfn/__init__.py +23 -0
  5. tabforge/_vendor/tabpfn/architectures/__init__.py +20 -0
  6. tabforge/_vendor/tabpfn/architectures/base/__init__.py +226 -0
  7. tabforge/_vendor/tabpfn/architectures/base/attention/__init__.py +62 -0
  8. tabforge/_vendor/tabpfn/architectures/base/attention/full_attention.py +703 -0
  9. tabforge/_vendor/tabpfn/architectures/base/bar_distribution.py +845 -0
  10. tabforge/_vendor/tabpfn/architectures/base/config.py +156 -0
  11. tabforge/_vendor/tabpfn/architectures/base/encoders.py +1143 -0
  12. tabforge/_vendor/tabpfn/architectures/base/layer.py +449 -0
  13. tabforge/_vendor/tabpfn/architectures/base/memory.py +200 -0
  14. tabforge/_vendor/tabpfn/architectures/base/mlp.py +138 -0
  15. tabforge/_vendor/tabpfn/architectures/base/tabpfn_col_embedding.pt +0 -0
  16. tabforge/_vendor/tabpfn/architectures/base/thinking_tokens.py +60 -0
  17. tabforge/_vendor/tabpfn/architectures/base/transformer.py +792 -0
  18. tabforge/_vendor/tabpfn/architectures/interface.py +167 -0
  19. tabforge/_vendor/tabpfn/base.py +574 -0
  20. tabforge/_vendor/tabpfn/classifier.py +1396 -0
  21. tabforge/_vendor/tabpfn/constants.py +85 -0
  22. tabforge/_vendor/tabpfn/finetune_utils.py +76 -0
  23. tabforge/_vendor/tabpfn/inference.py +789 -0
  24. tabforge/_vendor/tabpfn/inference_config.py +286 -0
  25. tabforge/_vendor/tabpfn/inference_tuning.py +417 -0
  26. tabforge/_vendor/tabpfn/misc/_sklearn_compat.py +863 -0
  27. tabforge/_vendor/tabpfn/misc/debug_versions.py +676 -0
  28. tabforge/_vendor/tabpfn/model/__init__.py +40 -0
  29. tabforge/_vendor/tabpfn/model/attention.py +5 -0
  30. tabforge/_vendor/tabpfn/model/bar_distribution.py +5 -0
  31. tabforge/_vendor/tabpfn/model/config.py +5 -0
  32. tabforge/_vendor/tabpfn/model/encoders.py +5 -0
  33. tabforge/_vendor/tabpfn/model/layer.py +5 -0
  34. tabforge/_vendor/tabpfn/model/loading.py +5 -0
  35. tabforge/_vendor/tabpfn/model/memory.py +5 -0
  36. tabforge/_vendor/tabpfn/model/mlp.py +5 -0
  37. tabforge/_vendor/tabpfn/model/preprocessing.py +5 -0
  38. tabforge/_vendor/tabpfn/model/transformer.py +5 -0
  39. tabforge/_vendor/tabpfn/model_loading.py +1022 -0
  40. tabforge/_vendor/tabpfn/parallel_execute.py +114 -0
  41. tabforge/_vendor/tabpfn/preprocessing.py +1116 -0
  42. tabforge/_vendor/tabpfn/preprocessors/__init__.py +51 -0
  43. tabforge/_vendor/tabpfn/preprocessors/adaptive_quantile_transformer.py +80 -0
  44. tabforge/_vendor/tabpfn/preprocessors/add_fingerprint_features_step.py +87 -0
  45. tabforge/_vendor/tabpfn/preprocessors/differentiable_z_norm_step.py +38 -0
  46. tabforge/_vendor/tabpfn/preprocessors/encode_categorical_features_step.py +233 -0
  47. tabforge/_vendor/tabpfn/preprocessors/kdi_transformer.py +113 -0
  48. tabforge/_vendor/tabpfn/preprocessors/nan_handling_polynomial_features_step.py +93 -0
  49. tabforge/_vendor/tabpfn/preprocessors/preprocessing_helpers.py +305 -0
  50. tabforge/_vendor/tabpfn/preprocessors/remove_constant_features_step.py +49 -0
  51. tabforge/_vendor/tabpfn/preprocessors/reshape_feature_distribution_step.py +608 -0
  52. tabforge/_vendor/tabpfn/preprocessors/safe_power_transformer.py +200 -0
  53. tabforge/_vendor/tabpfn/preprocessors/shuffle_features_step.py +68 -0
  54. tabforge/_vendor/tabpfn/preprocessors/squashing_scaler_transformer.py +389 -0
  55. tabforge/_vendor/tabpfn/regressor.py +1209 -0
  56. tabforge/_vendor/tabpfn/settings.py +96 -0
  57. tabforge/_vendor/tabpfn/utils.py +1064 -0
  58. tabforge/api/__init__.py +23 -0
  59. tabforge/api/base.py +1442 -0
  60. tabforge/api/estimators.py +1501 -0
  61. tabforge/checkpoints/README.md +20 -0
  62. tabforge/checkpoints/__init__.py +50 -0
  63. tabforge/checkpoints/canonical.py +292 -0
  64. tabforge/cli/__init__.py +429 -0
  65. tabforge/cli/__main__.py +6 -0
  66. tabforge/config/__init__.py +21 -0
  67. tabforge/config/config.py +378 -0
  68. tabforge/distributed.py +89 -0
  69. tabforge/embeddings/__init__.py +9 -0
  70. tabforge/embeddings/provider.py +907 -0
  71. tabforge/embeddings/sample_embedding.py +104 -0
  72. tabforge/embeddings/vendor-lock.json +15 -0
  73. tabforge/feature_processing/__init__.py +5 -0
  74. tabforge/feature_processing/processor.py +778 -0
  75. tabforge/models/__init__.py +27 -0
  76. tabforge/models/components.py +375 -0
  77. tabforge/models/diffusion.py +324 -0
  78. tabforge/models/losses.py +86 -0
  79. tabforge/training/__init__.py +11 -0
  80. tabforge/training/logging.py +90 -0
  81. tabforge/training/trainer.py +1458 -0
  82. tabforge_ml-2026.8.9.dist-info/METADATA +480 -0
  83. tabforge_ml-2026.8.9.dist-info/RECORD +86 -0
  84. tabforge_ml-2026.8.9.dist-info/WHEEL +4 -0
  85. tabforge_ml-2026.8.9.dist-info/entry_points.txt +2 -0
  86. tabforge_ml-2026.8.9.dist-info/licenses/LICENSE +201 -0
tabforge/__init__.py ADDED
@@ -0,0 +1,50 @@
1
+ """TabFORGE v1 public API."""
2
+
3
+ from ._metadata import MODEL_ID, __version__
4
+ from .api import (
5
+ TabFORGEAnomalyDetector,
6
+ TabFORGEClassifier,
7
+ TabFORGEClusterer,
8
+ TabFORGEEmbedder,
9
+ TabFORGEGenerator,
10
+ TabFORGEImputer,
11
+ TabFORGERegressor,
12
+ restore_from_checkpoint,
13
+ )
14
+ from .checkpoints import (
15
+ CHECKPOINT_FORMAT_VERSION,
16
+ detokeniser_compatibility_reason,
17
+ is_detokeniser_compatible,
18
+ official_checkpoint_path,
19
+ )
20
+ from .config import (
21
+ TabFORGEArchitectureConfig,
22
+ TabFORGEDiffusionConfig,
23
+ TabFORGEEmbeddingConfig,
24
+ TabFORGERuntimeConfig,
25
+ TabFORGESchedulerConfig,
26
+ TabFORGETrainingConfig,
27
+ )
28
+
29
+ __all__ = [
30
+ "CHECKPOINT_FORMAT_VERSION",
31
+ "MODEL_ID",
32
+ "__version__",
33
+ "TabFORGEArchitectureConfig",
34
+ "TabFORGEAnomalyDetector",
35
+ "TabFORGEClassifier",
36
+ "TabFORGEClusterer",
37
+ "TabFORGEDiffusionConfig",
38
+ "TabFORGEEmbedder",
39
+ "TabFORGEEmbeddingConfig",
40
+ "TabFORGEGenerator",
41
+ "TabFORGEImputer",
42
+ "TabFORGERuntimeConfig",
43
+ "TabFORGESchedulerConfig",
44
+ "TabFORGERegressor",
45
+ "TabFORGETrainingConfig",
46
+ "official_checkpoint_path",
47
+ "restore_from_checkpoint",
48
+ "detokeniser_compatibility_reason",
49
+ "is_detokeniser_compatible",
50
+ ]
tabforge/_metadata.py ADDED
@@ -0,0 +1,4 @@
1
+ """Package and model identifiers shared by artifacts and public metadata."""
2
+
3
+ __version__ = "2026.8.9"
4
+ MODEL_ID = "tabforge-v1"
@@ -0,0 +1 @@
1
+ """Private vendored runtimes."""
@@ -0,0 +1,23 @@
1
+ from importlib.metadata import version
2
+
3
+ from tabforge._vendor.tabpfn.classifier import TabPFNClassifier
4
+ from tabforge._vendor.tabpfn.misc.debug_versions import display_debug_info
5
+ from tabforge._vendor.tabpfn.model_loading import (
6
+ load_fitted_tabpfn_model,
7
+ save_fitted_tabpfn_model,
8
+ )
9
+ from tabforge._vendor.tabpfn.regressor import TabPFNRegressor
10
+
11
+ try:
12
+ __version__ = version(__name__)
13
+ except ImportError:
14
+ __version__ = "unknown"
15
+
16
+ __all__ = [
17
+ "TabPFNClassifier",
18
+ "TabPFNRegressor",
19
+ "__version__",
20
+ "display_debug_info",
21
+ "load_fitted_tabpfn_model",
22
+ "save_fitted_tabpfn_model",
23
+ ]
@@ -0,0 +1,20 @@
1
+ """Contains a collection of different model architectures.
2
+
3
+ "Architecture" refers to a PyTorch module, which is then wrapped by e.g.
4
+ TabPFNClassifier or TabPFNRegressor to form the complete model.
5
+
6
+ Each submodule in this module should contain an architecture. Each may be a directory,
7
+ or just a single file.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from typing import TYPE_CHECKING
13
+
14
+ from . import base
15
+
16
+ if TYPE_CHECKING:
17
+ from tabforge._vendor.tabpfn.architectures.interface import ArchitectureModule
18
+
19
+ ARCHITECTURES: dict[str, ArchitectureModule] = {"base": base}
20
+ """Map from architecture names to the corresponding module."""
@@ -0,0 +1,226 @@
1
+ """The base architecture.
2
+
3
+ This is the original model before we switched to the multiple architecture arrangement.
4
+ It is a single architecture which implements many different functionalities. Other
5
+ architectures can import components from here to reuse them, and over time we should
6
+ refactor this architecture to improve reusability.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from typing import TYPE_CHECKING, Any, Literal
12
+
13
+ from tabforge._vendor.tabpfn.architectures.base.config import ModelConfig
14
+ from tabforge._vendor.tabpfn.architectures.base.encoders import (
15
+ InputNormalizationEncoderStep,
16
+ LinearInputEncoderStep,
17
+ MLPInputEncoderStep,
18
+ MulticlassClassificationTargetEncoder,
19
+ NanHandlingEncoderStep,
20
+ RemoveDuplicateFeaturesEncoderStep,
21
+ RemoveEmptyFeaturesEncoderStep,
22
+ SeqEncStep,
23
+ SequentialEncoder,
24
+ VariableNumFeaturesEncoderStep,
25
+ )
26
+ from tabforge._vendor.tabpfn.architectures.base.transformer import PerFeatureTransformer
27
+
28
+ if TYPE_CHECKING:
29
+ from torch import nn
30
+
31
+ from tabforge._vendor.tabpfn.architectures.interface import ArchitectureConfig
32
+
33
+
34
+ def parse_config(config: dict[str, Any]) -> tuple[ArchitectureConfig, dict[str, Any]]:
35
+ """Parse the config dict into a ModelConfig, a subclass of ArchitectureConfig.
36
+
37
+ This method implements the interface defined in
38
+ tabpfn.architectures.interface.ArchitectureModule.parse_config().
39
+
40
+ Unrecognised keys should be ignored during parsing, and returned in the `unused
41
+ config items` dict.
42
+
43
+ Args:
44
+ config: Config dict to parse. This function should use Pydantic to
45
+ verify that it matches the expected schema.
46
+
47
+ Returns: a tuple (the parsed config, dict containing unused config items)
48
+
49
+ Raises:
50
+ pydantic.ValidationError: one or more of the values have the wrong type
51
+ """
52
+ upgraded_dict = ModelConfig.upgrade_config(config)
53
+ parsed_config = ModelConfig(**upgraded_dict)
54
+ return parsed_config, parsed_config.get_unused_config(upgraded_dict)
55
+
56
+
57
+ def get_architecture(
58
+ config: ArchitectureConfig,
59
+ *,
60
+ n_out: int,
61
+ cache_trainset_representation: bool,
62
+ ) -> PerFeatureTransformer:
63
+ """Construct the base architecture following the given config.
64
+
65
+ This factory method implements the interface defined in
66
+ tabpfn.architectures.interface.ArchitectureModule.get_architecture().
67
+
68
+ Args:
69
+ config: The config returned by parse_config(). This method should use a
70
+ runtime isinstance() check to downcast the config to this architecture's
71
+ specific config class.
72
+ n_out: The number of output classes that the model should predict.
73
+ cache_trainset_representation: If True, the model should be configured to
74
+ cache the training data during inference to improve speed.
75
+
76
+ Returns: the constructed architecture
77
+ """
78
+ assert isinstance(config, ModelConfig)
79
+ return PerFeatureTransformer(
80
+ config=config,
81
+ # Things that were explicitly passed inside `build_model()`
82
+ encoder=get_encoder(
83
+ num_features=config.features_per_group,
84
+ embedding_size=config.emsize,
85
+ remove_empty_features=config.remove_empty_features,
86
+ remove_duplicate_features=config.remove_duplicate_features,
87
+ nan_handling_enabled=config.nan_handling_enabled,
88
+ normalize_on_train_only=config.normalize_on_train_only,
89
+ normalize_to_ranking=config.normalize_to_ranking,
90
+ normalize_x=config.normalize_x,
91
+ remove_outliers=config.remove_outliers,
92
+ normalize_by_used_features=config.normalize_by_used_features,
93
+ encoder_use_bias=config.encoder_use_bias,
94
+ encoder_type=config.encoder_type,
95
+ encoder_mlp_hidden_dim=config.encoder_mlp_hidden_dim,
96
+ encoder_mlp_num_layers=config.encoder_mlp_num_layers,
97
+ ),
98
+ y_encoder=get_y_encoder(
99
+ num_inputs=1,
100
+ embedding_size=config.emsize,
101
+ nan_handling_y_encoder=config.nan_handling_y_encoder,
102
+ max_num_classes=config.max_num_classes,
103
+ ),
104
+ cache_trainset_representation=cache_trainset_representation,
105
+ use_encoder_compression_layer=False,
106
+ n_out=n_out,
107
+ #
108
+ # These are things that had default values from config.get() but were not
109
+ # present in any config.
110
+ layer_norm_with_elementwise_affine=False,
111
+ )
112
+
113
+
114
+ def get_encoder( # noqa: PLR0913
115
+ *,
116
+ num_features: int,
117
+ embedding_size: int,
118
+ remove_empty_features: bool,
119
+ remove_duplicate_features: bool,
120
+ nan_handling_enabled: bool,
121
+ normalize_on_train_only: bool,
122
+ normalize_to_ranking: bool,
123
+ normalize_x: bool,
124
+ remove_outliers: bool,
125
+ normalize_by_used_features: bool,
126
+ encoder_use_bias: bool,
127
+ encoder_type: Literal["linear", "mlp"] = "linear",
128
+ encoder_mlp_hidden_dim: int | None = None,
129
+ encoder_mlp_num_layers: int = 2,
130
+ ) -> nn.Module:
131
+ inputs_to_merge = {"main": {"dim": num_features}}
132
+
133
+ encoder_steps: list[SeqEncStep] = []
134
+ if remove_empty_features:
135
+ encoder_steps += [RemoveEmptyFeaturesEncoderStep()]
136
+
137
+ if remove_duplicate_features:
138
+ encoder_steps += [RemoveDuplicateFeaturesEncoderStep()]
139
+
140
+ encoder_steps += [NanHandlingEncoderStep(keep_nans=nan_handling_enabled)]
141
+
142
+ if nan_handling_enabled:
143
+ inputs_to_merge["nan_indicators"] = {"dim": num_features}
144
+
145
+ encoder_steps += [
146
+ VariableNumFeaturesEncoderStep(
147
+ num_features=num_features,
148
+ normalize_by_used_features=False,
149
+ in_keys=["nan_indicators"],
150
+ out_keys=["nan_indicators"],
151
+ ),
152
+ ]
153
+
154
+ encoder_steps += [
155
+ InputNormalizationEncoderStep(
156
+ normalize_on_train_only=normalize_on_train_only,
157
+ normalize_to_ranking=normalize_to_ranking,
158
+ normalize_x=normalize_x,
159
+ remove_outliers=remove_outliers,
160
+ ),
161
+ ]
162
+
163
+ encoder_steps += [
164
+ VariableNumFeaturesEncoderStep(
165
+ num_features=num_features,
166
+ normalize_by_used_features=normalize_by_used_features,
167
+ ),
168
+ ]
169
+
170
+ num_input_features = sum(i["dim"] for i in inputs_to_merge.values())
171
+ if encoder_type == "mlp":
172
+ encoder_steps += [
173
+ MLPInputEncoderStep(
174
+ num_features=num_input_features,
175
+ emsize=embedding_size,
176
+ hidden_dim=encoder_mlp_hidden_dim,
177
+ activation="gelu",
178
+ num_layers=encoder_mlp_num_layers,
179
+ bias=encoder_use_bias,
180
+ in_keys=tuple(inputs_to_merge),
181
+ out_keys=("output",),
182
+ ),
183
+ ]
184
+ elif encoder_type == "linear":
185
+ encoder_steps += [
186
+ LinearInputEncoderStep(
187
+ num_features=num_input_features,
188
+ emsize=embedding_size,
189
+ bias=encoder_use_bias,
190
+ in_keys=tuple(inputs_to_merge),
191
+ out_keys=("output",),
192
+ ),
193
+ ]
194
+ else:
195
+ raise ValueError(
196
+ f"Invalid encoder type: {encoder_type} (expected 'linear' or 'mlp')"
197
+ )
198
+
199
+ return SequentialEncoder(*encoder_steps, output_key="output")
200
+
201
+
202
+ def get_y_encoder(
203
+ *,
204
+ num_inputs: int,
205
+ embedding_size: int,
206
+ nan_handling_y_encoder: bool,
207
+ max_num_classes: int,
208
+ ) -> nn.Module:
209
+ steps: list[SeqEncStep] = []
210
+ inputs_to_merge = [{"name": "main", "dim": num_inputs}]
211
+ if nan_handling_y_encoder:
212
+ steps += [NanHandlingEncoderStep()]
213
+ inputs_to_merge += [{"name": "nan_indicators", "dim": num_inputs}]
214
+
215
+ if max_num_classes >= 2:
216
+ steps += [MulticlassClassificationTargetEncoder()]
217
+
218
+ steps += [
219
+ LinearInputEncoderStep(
220
+ num_features=sum([i["dim"] for i in inputs_to_merge]), # type: ignore
221
+ emsize=embedding_size,
222
+ in_keys=tuple(i["name"] for i in inputs_to_merge), # type: ignore
223
+ out_keys=("output",),
224
+ ),
225
+ ]
226
+ return SequentialEncoder(*steps, output_key="output")
@@ -0,0 +1,62 @@
1
+ from __future__ import annotations
2
+
3
+ from abc import ABC, abstractmethod
4
+ from typing_extensions import override
5
+
6
+ import torch
7
+ from torch import nn
8
+
9
+
10
+ class Attention(ABC, nn.Module):
11
+ """Base class for attention layers."""
12
+
13
+ @override
14
+ @abstractmethod
15
+ def forward(
16
+ self,
17
+ x: torch.Tensor,
18
+ x_kv: torch.Tensor | None = None,
19
+ *,
20
+ cache_kv: bool = False,
21
+ use_cached_kv: bool = False,
22
+ reuse_first_head_kv: bool = False,
23
+ only_cache_first_head_kv: bool = False,
24
+ save_peak_mem_factor: int | None = None,
25
+ add_input: bool = False,
26
+ allow_inplace: bool = False,
27
+ ) -> torch.Tensor:
28
+ """Performs the attention layer.
29
+
30
+ Args:
31
+ x: Input sequence of embeddings with shape
32
+ [batch... x query seq len x embedding dim].
33
+ If `x_kv` is None, this is used to compute the queries, keys, and
34
+ values.
35
+ If `x_kv` is not None, this is used to compute the queries only.
36
+ x_kv: If not None, an input sequence of embeddings with shape
37
+ [batch... x kv seq len x embedding dim].
38
+ It will be used to compute the keys and the values, with `x` used only
39
+ to compute the queries. This is useful to avoid some sequence positions
40
+ attending to others.
41
+ cache_kv: If True, replaces the current key-value cache with the keys and
42
+ values computed during this forward pass. Otherwise, the KV cache is
43
+ left unchanged. If True, `use_cached_kv` must be False.
44
+ use_cached_kv: If True, uses the keys and values cached during a previous
45
+ forward pass when `cache_kv` was True. If True, `cache_kv` must be
46
+ False.
47
+ reuse_first_head_kv: If True, then uses the keys and values projected in the
48
+ first head for all the heads.
49
+ only_cache_first_head_kv: When True, only caches the keys and values of the
50
+ first head.
51
+ save_peak_mem_factor: Loops over the batch dimension rather than processing
52
+ it in parallel, to reduce memory usage.
53
+ add_input: If True, returns (x+the output of attention), i.e. enables a
54
+ residual connection. If False, just returns the output of attention.
55
+ allow_inplace: By setting this to True, the caller indicates that 'x' is not
56
+ used after the call and its buffer can be reused for the output.
57
+ The operation is not guaranteed to be inplace.
58
+
59
+ Returns:
60
+ Output hidden states of shape [batch x query seq len x embedding dim]
61
+ """
62
+ ...