Skip to content

ChimeraBoost 0.30.0, AutoGluon 1.6 model API migration, and four model fixes - #468

Merged
LennartPurucker merged 7 commits into
mainfrom
add_new_chimera
Aug 11, 2026
Merged

ChimeraBoost 0.30.0, AutoGluon 1.6 model API migration, and four model fixes#468
LennartPurucker merged 7 commits into
mainfrom
add_new_chimera

Conversation

@LennartPurucker

@LennartPurucker LennartPurucker commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Closes #463.

ChimeraBoost 0.30.0

Bumps the pin to chimeraboost>=0.30.0 (info.py + pyproject.toml) for the re-run requested in #463. Pre-flight before spending cluster time: all 13 search-space parameters still exist in 0.30.0, and all 201 configs (default + 200 random) fit on binary/multiclass/regression. The only warning is the documented multiclass no-op for leaf_estimation_iterations. fit(cat_features=, eval_set=, callbacks=) and the cb(iteration, train_loss, val_loss, model) signature are unchanged, so the wrapper's time-limit callback still works.

Worth knowing for interpreting the results: 0.30.0's headline refit_full="replay" default is inert here by design. It only fires for fits that use ChimeraBoost's own internal split, and the wrapper passes AutoGluon's bagging validation fold as an explicit eval_set. Refitting on that fold would train on the rows whose predictions become the out-of-fold predictions used for scoring and ensembling.

AutoGluon 1.6 model API migration

AutoGluon 1.6 replaced a set of override methods with class attributes. Only _supported_problem_types is enforced, but FitHelper.verify_model raises on the old override, so pytest -m models was failing for 25 registry entries (20 classes) without ever reaching a model fit.

Override Replaced by Count
supported_problem_types() _supported_problem_types 20
_get_default_resources() default_resources_physical_cores_only + default_num_gpus 17
get_minimum_resources() minimum_num_gpus 14
_get_default_ag_args_ensemble() _default_ag_args_ensemble_extra 14
_get_default_auxiliary_params() _default_auxiliary_params_extra 8

Also removes now-dead code: 15 _class_tags declaring only can_estimate_memory_usage_static (AutoGluon derives it from whether _estimate_memory_usage_static is implemented) and 9 _estimate_memory_usage methods that only forwarded to the static estimate (now the base default). 12 methods were deliberately left alone where the body reads the parent's resolved value via .pop() or branches on state.

Verified behaviour-neutral by snapshotting every registry model's memory-estimate and default-resolution behaviour to JSON before and after. Memory behaviour is identical across all 37 models. The one difference is that get_minimum_resources no longer returns num_gpus: 0 when no GPU is present; every consumer in AutoGluon core reads .get("num_gpus", 0), so absent and 0 are equivalent.

The add-model and benchmark-model skill docs are updated to teach the new API.

Four model fixes the migration uncovered

The supported_problem_types assertion fires before the model fits, so it had been masking real failures.

  1. TabPFN-2.6 large data_adjust_hyperparameters_for_large_data imported _get_v2_6_config and the v2_6_* preprocessor factories, which no longer exist: v2.6 checkpoints embed their own InferenceConfig, so those defaults were removed upstream. Any dataset above 70k rows and 300 features died with ImportError mid-fit. Now reads the checkpoint's own transforms via get_inference_config() and passes a dict override, so override_with_user_input_and_resolve_auto merges it and every unnamed field keeps the checkpoint's value. The shipped caps turn out to be 680/500, so capping to 300 preserves the original intent.

  2. LimiX unpicklable encoder_NaNCleanEncoder was defined inside a functools.cached factory, giving it the qualname _nan_clean_encoder_cls.<locals>._NaNCleanEncoder, which pickle rejects. Every fitted LimiX model was unpicklable, and bagging pickles each fold child back to the parent. Keeps the factory (its lazy-torch purpose is real), rewrites the qualname, and adds a module __getattr__ that resolves it. Verified to round-trip and to unpickle in a cold process that never called the factory, with torch still absent from sys.modules on import.

  3. TabSwift single-vs-batched predictions — differed by ~2.4e-4 against a 1e-5 tolerance. Running FitHelper.verify_model with CUDA_VISIBLE_DEVICES="" passes with the check on, so this is float non-determinism in the CUDA kernels, not batch-dependent preprocessing. Adds verify_single_prediction_equivalent_to_multi to ModelSmokeTest and sets it False for TabSwift, with the CPU evidence recorded.

  4. TabDPTTabDPT_GPU runs the tabdpt1_1 checkpoint, whose architecture config has 8 keys and no enc_cell_dim; tabdpt 1.2.0's loader reads v1.2-only keys with no legacy branch. Not a stale cache: forcing an upstream revision check returned the same revision. Its pin is corrected to tabdpt<1.2 and it is marked superseded=True, a new ModelInfo flag that keeps a replaced entry's conflicting pin out of the installable extras and skips it in the smoke tests. TabDPT-Turbo is the current default and keeps >=1.2.0.

Test status

pytest -m models tests/tabarena/models/test_all_models.py: 24 passed, 12 skipped, 1 failed, against 23 passed / 11 skipped / 3 failed before this branch. LimiX and TabSwift now pass, TabDPT_GPU skips with an explicit reason, and the other 11 skips are missing optional dependencies in this environment.

The one failure is Mitra_GPU, which is pre-existing, flaky, and outside this branch:

  • It is AutoGluon's own model (autogluon.tabular.models.mitra.mitra_model.MitraModel), not a TabArena wrapper, and nothing here touches it.
  • It fails the same single-vs-batched prediction check as TabSwift, but on CPU as well as GPU, and by a larger margin on CPU (~8e-4 vs ~4.7e-5). So it is genuine batch-composition dependence, not CUDA float noise, and it deliberately does not get TabSwift's verify_single_prediction_equivalent_to_multi=False opt-out — that field is restricted to models proven to pass on CPU.
  • Two identical GPU runs of that single test gave one pass and one failure, so it has been passing by luck rather than being newly broken.

Worth reporting upstream to AutoGluon separately.

Lint and format are clean on every file touched; the only ruff check error in the tree is the pre-existing PLR0917 in tests/tabarena/repository/test_repository.py.

🤖 Generated with Claude Code

LennartPurucker and others added 5 commits August 10, 2026 08:46
`ModelInfo.superseded` keeps a replaced entry's pin out of the pyproject extras.
Without it TabDPT_GPU's `tabdpt<1.2` unions with TabDPT-Turbo's `tabdpt>=1.2.0`
into one unresolvable extra, which would break `pip install tabarena[benchmark]`
in CI.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@LennartPurucker

Copy link
Copy Markdown
Collaborator Author

FYI @bbstats, here is the PR for tracking the progress for #463

@LennartPurucker

Copy link
Copy Markdown
Collaborator Author

Closes #463

mario-koddenbrock added a commit to ml-lab-htw/RamanBench that referenced this pull request Aug 10, 2026
tabarena.models.limix.model._nan_clean_encoder_cls() builds its NaN-sanitizing
nn.Module wrapper as a class local to the factory function (deliberately, to
keep torch off that module's import path), which gets an unresolvable qualname
(_nan_clean_encoder_cls.<locals>._NaNCleanEncoder). AutoGluon's bagged-ensemble
save_child() pickles every fold child right after it finishes training, so
every LIMIX run crashed at that step -- confirmed on 4/4 real cluster runs
(classification and regression alike), always right after training completed.

Already reported and fixed upstream in
autogluon/tabarena#468 (open, not yet merged/released
as of 2026-08-10). wrapped_models._patch_limix_pickle_bug reproduces that exact
fix at runtime -- rewrites the produced class's __qualname__ and adds a
module-level __getattr__ (PEP 562) that rebuilds/returns the same,
functools.cache-stable class on demand -- and is applied automatically to the
installed tabarena package at import time, idempotent, and a no-op once the
real fix ships.

Verified with a real TabularPredictor.fit()/.save()/.predict() run (bagged, 2
folds, CPU): crashes pre-patch at exactly save_child(), succeeds post-patch,
and a saved predictor loads and predicts correctly in a cold process that
never called the factory. Full test suite (113 tests) passes unchanged.
@mario-koddenbrock

Copy link
Copy Markdown
Contributor

Independently reproduced this bug via LIMIX in a downstream benchmark (RamanBench) — pickling failed at AutoGluon's save_child() right after training completed, on both classification and regression, every run. Verified this fix (rewriting __qualname__ + module-level __getattr__) resolves it in both same-process and cold-process unpickling. Thanks for the fast turnaround.

@LennartPurucker

Copy link
Copy Markdown
Collaborator Author

@mario-koddenbrock let me know if it would help you if I merge this now. Otherwise, I am waiting for the runs to finish (by the end of day/tomorrow morning).

@mario-koddenbrock

Copy link
Copy Markdown
Contributor

@LennartPurucker No, it's not urgent at all. Thanks :)

@LennartPurucker

Copy link
Copy Markdown
Collaborator Author

Here are the results, nice gains!

tabarena-pareto-explorer-train-time tabarena-pareto-explorer

LennartPurucker and others added 2 commits August 11, 2026 07:58
Register the chimeraboost_10082026 rerun on ChimeraBoost 0.30.0, whose reworked algorithm improves
regression and small-data accuracy and speeds up large data (#463). Same run shape as the 0.14.1
runs, so accuracy and timings stay comparable: rank 28 -> 21 on the default leaderboard.

The default arena collection now carries only the new suite; both 0.14.1 runs stay reachable through
the complete collection. The two per-date superseded lists collapse into one `methods_superseded`,
since the date in `methods_superseded_2026_07_13` named the rerun that displaced those entries rather
than the suite they ran in, so a second dated list would have used the same suffix for the opposite
meaning. Behavior is unchanged (42 current / 76 complete methods).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
BENCHMARK_LOG.md entries were only ever offered by benchmark-model, at launch time and before any
results exist, so runs reached upload unlogged. Give upload-method a step that checks for the entry
once the run is finished, including how to recover the setup-time SHA from the reflog and the run's
own timestamps. Also document the rerun case: registering a rerun is a swap plus a
`methods_superseded` append, not an addition.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@LennartPurucker
LennartPurucker merged commit 735665f into main Aug 11, 2026
7 checks passed
@LennartPurucker
LennartPurucker deleted the add_new_chimera branch August 11, 2026 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for ChimeraBoost 0.30.0

2 participants