Skip to content

Catch and Handle Preprocessing Errors #183

Description

@1511878618

Describe the bug

When i run this code with a train set shape (10000, 30)

from tabpfn_extensions.post_hoc_ensembles.sklearn_interface import AutoTabPFNClassifier

AutoTabPFN = AutoTabPFNClassifier(max_time=120, device='cuda') # 120 seconds tuning time
AutoTabPFN.fit(X_train, y_train)

It raised this errors:

---------------------------------------------------------------------------
BracketError                              Traceback (most recent call last)
Cell In[20], line 4
      1 from tabpfn_extensions.post_hoc_ensembles.sklearn_interface import AutoTabPFNClassifier
      3 AutoTabPFN = AutoTabPFNClassifier(max_time=120, device='cuda') # 120 seconds tuning time
----> 4 AutoTabPFN.fit(X_train, y_train)

File /deeplearning/xutingfeng/project/tabpfn-community/src/tabpfn_extensions/post_hoc_ensembles/sklearn_interface.py:112, in AutoTabPFNClassifier.fit(self, X, y, categorical_feature_indices)
     97 task_type = (
     98     TaskType.MULTICLASS if len(unique_labels(y)) > 2 else TaskType.BINARY
     99 )
    100 self.predictor_ = AutoPostHocEnsemblePredictor(
    101     preset=self.preset,
    102     task_type=task_type,
   (...)
    109     **self.phe_init_args_,
    110 )
--> 112 self.predictor_.fit(
    113     X,
    114     y,
    115     categorical_feature_indices=self.categorical_feature_indices,
    116 )
    118 # -- Sklearn required values
    119 self.classes_ = self.predictor_._label_encoder.classes_

File /deeplearning/xutingfeng/project/tabpfn-community/src/tabpfn_extensions/post_hoc_ensembles/pfn_phe.py:333, in AutoPostHocEnsemblePredictor.fit(self, X, y, categorical_feature_indices)
    316 self._estimators, model_family_per_estimator = self._collect_base_models(
    317     categorical_feature_indices=categorical_feature_indices,
    318 )
    320 self._ens_model = self._ens_model(
    321     estimators=self._estimators,
    322     seed=self.ges_random_state,
   (...)
    330     model_family_per_estimator=model_family_per_estimator,
    331 )
--> 333 self._ens_model.fit(X, y)
    335 return self

File /deeplearning/xutingfeng/project/tabpfn-community/src/tabpfn_extensions/post_hoc_ensembles/greedy_weighted_ensemble.py:234, in GreedyWeightedEnsemble.fit(self, X, y)
    233 def fit(self, X, y):
--> 234     weights = self.get_weights(X, y)
    236     final_weights = []
    237     base_models = []

File /deeplearning/xutingfeng/project/tabpfn-community/src/tabpfn_extensions/post_hoc_ensembles/greedy_weighted_ensemble.py:173, in GreedyWeightedEnsemble.get_weights(self, X, y)
    172 def get_weights(self, X, y):
--> 173     oof_proba = self.get_oof_per_estimator(X, y)
    174     self.model_family_per_estimator = (
    175         self.model_family_per_estimator
    176         if self.model_family_per_estimator is not None
    177         else ["X"] * len(self._estimators)
    178     )
    179     self._model_family_per_estimator = self.model_family_per_estimator[
    180         : len(self._estimators)
    181     ]

File /deeplearning/xutingfeng/project/tabpfn-community/src/tabpfn_extensions/post_hoc_ensembles/abstract_validation_utils.py:372, in AbstractValidationUtils.get_oof_per_estimator(self, X, y, return_loss_per_estimator, impute_dropped_instances, _extra_processing)
    369     to_pass_holdout_index_hits = holdout_index_hits
    370     holdout_index_hit_counts = current_repeat
--> 372 self._fill_predictions_in_place(
    373     model_i=model_i,
    374     base_model=base_model,
    375     oof_proba_list=oof_proba_list,
    376     X=X,
    377     y=y,
    378     train_index=train_index,
    379     test_index=test_index,
    380     loss_per_estimator=loss_per_estimator,
    381     holdout_index_hits=to_pass_holdout_index_hits,
    382     split_i=split_i,
    383     _extra_processing=_extra_processing,
    384 )
    386 if check_for_repeat_early_stopping:  # True after every repeat.
    387     ran_repeats = current_repeat

File /deeplearning/xutingfeng/project/tabpfn-community/src/tabpfn_extensions/post_hoc_ensembles/abstract_validation_utils.py:127, in AbstractValidationUtils._fill_predictions_in_place(self, model_i, base_model, oof_proba_list, X, y, train_index, test_index, loss_per_estimator, holdout_index_hits, _extra_processing, split_i)
    123 fold_y_train, fold_y_test = y[train_index], y[test_index]
    124 # base_model = copy.deepcopy(base_model) # FIXME: think about adding this for safety but will likely slow down (due to having to load model again)
    125 
    126 # Default base models case
--> 127 base_model.fit(fold_X_train, fold_y_train)
    129 pred = self._predict_oof(base_model, fold_X_test)
    131 oof_proba_list[model_i][test_index] += pred

File /deeplearning/xutingfeng/project/TabPFN/src/tabpfn/classifier.py:489, in TabPFNClassifier.fit(self, X, y)
    486 assert len(ensemble_configs) == self.n_estimators
    488 # Create the inference engine
--> 489 self.executor_ = create_inference_engine(
    490     X_train=X,
    491     y_train=y,
    492     model=self.model_,
    493     ensemble_configs=ensemble_configs,
    494     cat_ix=self.inferred_categorical_indices_,
    495     fit_mode=self.fit_mode,
    496     device_=self.device_,
    497     rng=rng,
    498     n_jobs=self.n_jobs,
    499     byte_size=byte_size,
    500     forced_inference_dtype_=self.forced_inference_dtype_,
    501     memory_saving_mode=self.memory_saving_mode,
    502     use_autocast_=self.use_autocast_,
    503 )
    505 return self

File /deeplearning/xutingfeng/project/TabPFN/src/tabpfn/base.py:213, in create_inference_engine(X_train, y_train, model, ensemble_configs, cat_ix, fit_mode, device_, rng, n_jobs, byte_size, forced_inference_dtype_, memory_saving_mode, use_autocast_)
    200     engine = InferenceEngineOnDemand.prepare(
    201         X_train=X_train,
    202         y_train=y_train,
   (...)
    210         save_peak_mem=memory_saving_mode,
    211     )
    212 elif fit_mode == "fit_preprocessors":
--> 213     engine = InferenceEngineCachePreprocessing.prepare(
    214         X_train=X_train,
    215         y_train=y_train,
    216         cat_ix=cat_ix,
    217         ensemble_configs=ensemble_configs,
    218         n_workers=n_jobs,
    219         model=model,
    220         rng=rng,
    221         dtype_byte_size=byte_size,
    222         force_inference_dtype=forced_inference_dtype_,
    223         save_peak_mem=memory_saving_mode,
    224     )
    225 elif fit_mode == "fit_with_cache":
    226     engine = InferenceEngineCacheKV.prepare(
    227         X_train=X_train,
    228         y_train=y_train,
   (...)
    238         autocast=use_autocast_,
    239     )

File /deeplearning/xutingfeng/project/TabPFN/src/tabpfn/inference.py:265, in InferenceEngineCachePreprocessing.prepare(cls, X_train, y_train, cat_ix, model, ensemble_configs, n_workers, rng, dtype_byte_size, force_inference_dtype, save_peak_mem)
    239 """Prepare the inference engine.
    240 
    241 Args:
   (...)
    254     The prepared inference engine.
    255 """
    256 itr = fit_preprocessing(
    257     configs=ensemble_configs,
    258     X_train=X_train,
   (...)
    263     parallel_mode="block",
    264 )
--> 265 configs, preprocessors, X_trains, y_trains, cat_ixs = list(zip(*itr))
    266 return InferenceEngineCachePreprocessing(
    267     X_trains=X_trains,
    268     y_trains=y_trains,
   (...)
    275     save_peak_mem=save_peak_mem,
    276 )

File /deeplearning/xutingfeng/project/TabPFN/src/tabpfn/preprocessing.py:664, in fit_preprocessing(configs, X_train, y_train, random_state, cat_ix, n_workers, parallel_mode)
    661 worker_func = joblib.delayed(func)
    663 seeds = rng.integers(0, np.iinfo(np.int32).max, len(configs))
--> 664 yield from executor(  # type: ignore
    665     [
    666         worker_func(config, X_train, y_train, seed)
    667         for config, seed in zip(configs, seeds)
    668     ],
    669 )

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/joblib/parallel.py:1918, in Parallel.__call__(self, iterable)
   1916     output = self._get_sequential_output(iterable)
   1917     next(output)
-> 1918     return output if self.return_generator else list(output)
   1920 # Let's create an ID that uniquely identifies the current call. If the
   1921 # call is interrupted early and that the same instance is immediately
   1922 # re-used, this id will be used to prevent workers that were
   1923 # concurrently finalizing a task from the previous call to run the
   1924 # callback.
   1925 with self._lock:

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/joblib/parallel.py:1847, in Parallel._get_sequential_output(self, iterable)
   1845 self.n_dispatched_batches += 1
   1846 self.n_dispatched_tasks += 1
-> 1847 res = func(*args, **kwargs)
   1848 self.n_completed_tasks += 1
   1849 self.print_progress()

File /deeplearning/xutingfeng/project/TabPFN/src/tabpfn/preprocessing.py:571, in fit_preprocessing_one(config, X_train, y_train, random_state, cat_ix)
    568     y_train = y_train.copy()
    570 preprocessor = config.to_pipeline(random_state=static_seed)
--> 571 res = preprocessor.fit_transform(X_train, cat_ix)
    573 # TODO(eddiebergman): Not a fan of this, wish it was more transparent, but we want
    574 # to distuinguish what to do with the `ys` based on the ensemble config type
    575 if isinstance(config, RegressorEnsembleConfig):

File /deeplearning/xutingfeng/project/TabPFN/src/tabpfn/model/preprocessing.py:398, in SequentialFeatureTransformer.fit_transform(self, X, categorical_features)
    391 """Fit and transform the data using the fitted pipeline.
    392 
    393 Args:
    394     X: 2d array of shape (n_samples, n_features)
    395     categorical_features: list of indices of categorical features.
    396 """
    397 for step in self.steps:
--> 398     X, categorical_features = step.fit_transform(X, categorical_features)
    399     assert isinstance(categorical_features, list), (
    400         f"The {step=} must return list of categorical features,"
    401         f" but {type(step)} returned {categorical_features}"
    402     )
    404 self.categorical_features_ = categorical_features

File /deeplearning/xutingfeng/project/TabPFN/src/tabpfn/model/preprocessing.py:987, in ReshapeFeatureDistributionsStep.fit_transform(self, X, categorical_features)
    981 n_samples, n_features = X.shape
    982 transformer, cat_ix = self._set_transformer_and_cat_ix(
    983     n_samples,
    984     n_features,
    985     categorical_features,
    986 )
--> 987 Xt = transformer.fit_transform(X[:, self.subsampled_features_])
    988 self.categorical_features_after_transform_ = cat_ix
    989 self.transformer_ = transformer

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/sklearn/utils/_set_output.py:319, in _wrap_method_output.<locals>.wrapped(self, X, *args, **kwargs)
    317 @wraps(f)
    318 def wrapped(self, X, *args, **kwargs):
--> 319     data_to_wrap = f(self, X, *args, **kwargs)
    320     if isinstance(data_to_wrap, tuple):
    321         # only wrap the first output for cross decomposition
    322         return_tuple = (
    323             _wrap_data_with_container(method, data_to_wrap[0], X, self),
    324             *data_to_wrap[1:],
    325         )

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/sklearn/base.py:1389, in _fit_context.<locals>.decorator.<locals>.wrapper(estimator, *args, **kwargs)
   1382     estimator._validate_params()
   1384 with config_context(
   1385     skip_parameter_validation=(
   1386         prefer_skip_nested_validation or global_skip_validation
   1387     )
   1388 ):
-> 1389     return fit_method(estimator, *args, **kwargs)

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/sklearn/compose/_column_transformer.py:1001, in ColumnTransformer.fit_transform(self, X, y, **params)
    998 else:
    999     routed_params = self._get_empty_routing()
-> 1001 result = self._call_func_on_transformers(
   1002     X,
   1003     y,
   1004     _fit_transform_one,
   1005     column_as_labels=False,
   1006     routed_params=routed_params,
   1007 )
   1009 if not result:
   1010     self._update_fitted_transformers([])

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/sklearn/compose/_column_transformer.py:910, in ColumnTransformer._call_func_on_transformers(self, X, y, func, column_as_labels, routed_params)
    898             extra_args = {}
    899         jobs.append(
    900             delayed(func)(
    901                 transformer=clone(trans) if not fitted else trans,
   (...)
    907             )
    908         )
--> 910     return Parallel(n_jobs=self.n_jobs)(jobs)
    912 except ValueError as e:
    913     if "Expected 2D array, got 1D array instead" in str(e):

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/sklearn/utils/parallel.py:77, in Parallel.__call__(self, iterable)
     72 config = get_config()
     73 iterable_with_config = (
     74     (_with_config(delayed_func, config), args, kwargs)
     75     for delayed_func, args, kwargs in iterable
     76 )
---> 77 return super().__call__(iterable_with_config)

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/joblib/parallel.py:1918, in Parallel.__call__(self, iterable)
   1916     output = self._get_sequential_output(iterable)
   1917     next(output)
-> 1918     return output if self.return_generator else list(output)
   1920 # Let's create an ID that uniquely identifies the current call. If the
   1921 # call is interrupted early and that the same instance is immediately
   1922 # re-used, this id will be used to prevent workers that were
   1923 # concurrently finalizing a task from the previous call to run the
   1924 # callback.
   1925 with self._lock:

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/joblib/parallel.py:1847, in Parallel._get_sequential_output(self, iterable)
   1845 self.n_dispatched_batches += 1
   1846 self.n_dispatched_tasks += 1
-> 1847 res = func(*args, **kwargs)
   1848 self.n_completed_tasks += 1
   1849 self.print_progress()

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/sklearn/utils/parallel.py:139, in _FuncWrapper.__call__(self, *args, **kwargs)
    137     config = {}
    138 with config_context(**config):
--> 139     return self.function(*args, **kwargs)

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/sklearn/pipeline.py:1551, in _fit_transform_one(transformer, X, y, weight, message_clsname, message, params)
   1549 with _print_elapsed_time(message_clsname, message):
   1550     if hasattr(transformer, "fit_transform"):
-> 1551         res = transformer.fit_transform(X, y, **params.get("fit_transform", {}))
   1552     else:
   1553         res = transformer.fit(X, y, **params.get("fit", {})).transform(
   1554             X, **params.get("transform", {})
   1555         )

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/sklearn/base.py:1389, in _fit_context.<locals>.decorator.<locals>.wrapper(estimator, *args, **kwargs)
   1382     estimator._validate_params()
   1384 with config_context(
   1385     skip_parameter_validation=(
   1386         prefer_skip_nested_validation or global_skip_validation
   1387     )
   1388 ):
-> 1389     return fit_method(estimator, *args, **kwargs)

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/sklearn/pipeline.py:718, in Pipeline.fit_transform(self, X, y, **params)
    679 """Fit the model and transform with the final estimator.
    680 
    681 Fit all the transformers one after the other and sequentially transform
   (...)
    715     Transformed samples.
    716 """
    717 routed_params = self._check_method_params(method="fit_transform", props=params)
--> 718 Xt = self._fit(X, y, routed_params)
    720 last_step = self._final_estimator
    721 with _print_elapsed_time("Pipeline", self._log_message(len(self.steps) - 1)):

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/sklearn/pipeline.py:588, in Pipeline._fit(self, X, y, routed_params, raw_params)
    581 # Fit or load from cache the current transformer
    582 step_params = self._get_metadata_for_step(
    583     step_idx=step_idx,
    584     step_params=routed_params[name],
    585     all_params=raw_params,
    586 )
--> 588 X, fitted_transformer = fit_transform_one_cached(
    589     cloned_transformer,
    590     X,
    591     y,
    592     weight=None,
    593     message_clsname="Pipeline",
    594     message=self._log_message(step_idx),
    595     params=step_params,
    596 )
    597 # Replace the transformer of the step with the fitted
    598 # transformer. This is necessary when loading the transformer
    599 # from the cache.
    600 self.steps[step_idx] = (name, fitted_transformer)

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/joblib/memory.py:312, in NotMemorizedFunc.__call__(self, *args, **kwargs)
    311 def __call__(self, *args, **kwargs):
--> 312     return self.func(*args, **kwargs)

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/sklearn/pipeline.py:1551, in _fit_transform_one(transformer, X, y, weight, message_clsname, message, params)
   1549 with _print_elapsed_time(message_clsname, message):
   1550     if hasattr(transformer, "fit_transform"):
-> 1551         res = transformer.fit_transform(X, y, **params.get("fit_transform", {}))
   1552     else:
   1553         res = transformer.fit(X, y, **params.get("fit", {})).transform(
   1554             X, **params.get("transform", {})
   1555         )

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/sklearn/utils/_set_output.py:319, in _wrap_method_output.<locals>.wrapped(self, X, *args, **kwargs)
    317 @wraps(f)
    318 def wrapped(self, X, *args, **kwargs):
--> 319     data_to_wrap = f(self, X, *args, **kwargs)
    320     if isinstance(data_to_wrap, tuple):
    321         # only wrap the first output for cross decomposition
    322         return_tuple = (
    323             _wrap_data_with_container(method, data_to_wrap[0], X, self),
    324             *data_to_wrap[1:],
    325         )

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/sklearn/base.py:1389, in _fit_context.<locals>.decorator.<locals>.wrapper(estimator, *args, **kwargs)
   1382     estimator._validate_params()
   1384 with config_context(
   1385     skip_parameter_validation=(
   1386         prefer_skip_nested_validation or global_skip_validation
   1387     )
   1388 ):
-> 1389     return fit_method(estimator, *args, **kwargs)

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/sklearn/preprocessing/_data.py:3320, in PowerTransformer.fit_transform(self, X, y)
   3302 @_fit_context(prefer_skip_nested_validation=True)
   3303 def fit_transform(self, X, y=None):
   3304     """Fit `PowerTransformer` to `X`, then transform `X`.
   3305 
   3306     Parameters
   (...)
   3318         Transformed data.
   3319     """
-> 3320     return self._fit(X, y, force_transform=True)

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/sklearn/preprocessing/_data.py:3352, in PowerTransformer._fit(self, X, y, force_transform)
   3349     self.lambdas_[i] = 1.0
   3350     continue
-> 3352 self.lambdas_[i] = optim_function(col)
   3354 if self.standardize or force_transform:
   3355     X[:, i] = transform_function(X[:, i], self.lambdas_[i])

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/sklearn/preprocessing/_data.py:3530, in PowerTransformer._yeo_johnson_optimize(self, x)
   3528 x = x[~np.isnan(x)]
   3529 # choosing bracket -2, 2 like for boxcox
-> 3530 return optimize.brent(_neg_log_likelihood, brack=(-2, 2))

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/scipy/optimize/_optimize.py:2730, in brent(func, args, brack, tol, full_output, maxiter)
   2658 """
   2659 Given a function of one variable and a possible bracket, return
   2660 a local minimizer of the function isolated to a fractional precision
   (...)
   2726 
   2727 """
   2728 options = {'xtol': tol,
   2729            'maxiter': maxiter}
-> 2730 res = _minimize_scalar_brent(func, brack, args, **options)
   2731 if full_output:
   2732     return res['x'], res['fun'], res['nit'], res['nfev']

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/scipy/optimize/_optimize.py:2767, in _minimize_scalar_brent(func, brack, args, xtol, maxiter, disp, **unknown_options)
   2764 brent = Brent(func=func, args=args, tol=tol,
   2765               full_output=True, maxiter=maxiter, disp=disp)
   2766 brent.set_bracket(brack)
-> 2767 brent.optimize()
   2768 x, fval, nit, nfev = brent.get_result(full_output=True)
   2770 success = nit < maxiter and not (np.isnan(x) or np.isnan(fval))

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/scipy/optimize/_optimize.py:2537, in Brent.optimize(self)
   2534 def optimize(self):
   2535     # set up for optimization
   2536     func = self.func
-> 2537     xa, xb, xc, fa, fb, fc, funcalls = self.get_bracket_info()
   2538     _mintol = self._mintol
   2539     _cg = self._cg

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/scipy/optimize/_optimize.py:2506, in Brent.get_bracket_info(self)
   2504     xa, xb, xc, fa, fb, fc, funcalls = bracket(func, args=args)
   2505 elif len(brack) == 2:
-> 2506     xa, xb, xc, fa, fb, fc, funcalls = bracket(func, xa=brack[0],
   2507                                                xb=brack[1], args=args)
   2508 elif len(brack) == 3:
   2509     xa, xb, xc = brack

File /deeplearning/xutingfeng/miniforge3/envs/ml/lib/python3.11/site-packages/scipy/optimize/_optimize.py:3136, in bracket(func, xa, xb, args, grow_limit, maxiter)
   3134     e = BracketError(msg)
   3135     e.data = (xa, xb, xc, fa, fb, fc, funcalls)
-> 3136     raise e
   3138 return xa, xb, xc, fa, fb, fc, funcalls

BracketError: The algorithm terminated without finding a valid bracket. Consider trying different initial points.

Steps/Code to Reproduce

No response

Expected Results

No response

Actual Results

No response

Versions

tabpfn version:  2.0.5

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions