Skip to content

feat: add validation_frequency option to fine-tuning#1098

Open
Hemanth-1354 wants to merge 2 commits into
PriorLabs:mainfrom
Hemanth-1354:issue-811-validation-frequency
Open

feat: add validation_frequency option to fine-tuning#1098
Hemanth-1354 wants to merge 2 commits into
PriorLabs:mainfrom
Hemanth-1354:issue-811-validation-frequency

Conversation

@Hemanth-1354

Copy link
Copy Markdown

Issue

Closes #811

Motivation and Context

Fine-tuning currently validates every epoch unconditionally. For long runs
or large validation sets this adds overhead, and there's no way to disable
validation (and the early stopping that depends on it) when you don't need it.

This adds a validation_frequency: int | None = 1 parameter to
FinetunedTabPFNBase (and threads it through FinetunedTabPFNClassifier /
FinetunedTabPFNRegressor):

  • validation_frequency=1 (default): validates every epoch, identical to
    current behavior.
  • validation_frequency=N: validates (and checks early stopping) only every
    N epochs.
  • validation_frequency=None: skips validation for the entire run, which
    also disables early stopping. If early_stopping=True is passed alongside
    validation_frequency=None, a UserWarning is raised since the flag would
    otherwise silently have no effect.

Skipped epochs report NaN as the validation metric, reusing the existing
not np.isnan(...) guards already in the checkpoint-saving and
early-stopping code paths. Early stopping's restore-to-best-weights logic is
gated on a derived effective_early_stopping flag rather than the raw
self.early_stopping, so a run with validation_frequency=None can't
accidentally revert to the pre-training weights at the end.

Public API Changes

  • No Public API changes
  • Yes, Public API changes (Details below)

New optional keyword-only parameter validation_frequency on
FinetunedTabPFNBase.__init__, FinetunedTabPFNClassifier.__init__, and
FinetunedTabPFNRegressor.__init__. Defaults to 1, which preserves
existing behavior exactly, no breaking changes.

How Has This Been Tested?

  • Added test__finetuned_tabpfn_classifier__validation_frequency_skips_epochs:
    mocks _evaluate_model and asserts it's called only on the expected
    epochs (plus the one pre-loop baseline eval) when validation_frequency=2.
  • Added test__finetuned_tabpfn_classifier__validation_frequency_none_disables_es:
    asserts the UserWarning fires for early_stopping=True +
    validation_frequency=None, and that fine-tuned weights are not reverted
    to the base model despite early_stopping=True, proving early stopping is
    actually disabled rather than just skipped-but-still-restoring.
  • ruff check / ruff format --check pass on all changed files.
  • Existing finetuning test suite is unaffected (default validation_frequency=1
    reproduces the prior code path exactly).

Checklist

  • The changes have been tested locally.
  • Documentation has been updated (if the public API or usage changes).
  • A changelog entry has been added (see changelog/README.md), or "no changelog needed" label requested.
  • The code follows the project's style guidelines.
  • I have considered the impact of these changes on the public API.

Add validation_frequency parameter to FinetunedTabPFNBase/Classifier/
Regressor. Defaults to 1 (validate every epoch, current behavior).
N>1 validates every N epochs. None skips validation entirely for the
run and disables early stopping (warns if early_stopping=True was
also requested).

Closes PriorLabs#811
@CLAassistant

CLAassistant commented Jul 9, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a validation_frequency parameter to FinetunedTabPFNClassifier and FinetunedTabPFNRegressor, allowing validation and early stopping to run every N epochs or be disabled entirely when set to None. The feedback highlights two important issues: first, validation_frequency needs input validation to ensure it is a positive integer or None to avoid potential runtime errors like ZeroDivisionError; second, setting the primary metric to NaN on skipped epochs inadvertently prevents interval checkpoints from being saved, which should be corrected to allow checkpointing independently of validation runs.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/tabpfn/finetuning/finetuned_base.py
Comment thread src/tabpfn/finetuning/finetuned_base.py
@github-actions
github-actions Bot requested a review from anuragg1209 July 9, 2026 08:08
Address review comments on PriorLabs#1098:
- Raise ValueError for validation_frequency <= 0 or non-int (previously
  a bad value like 0 would cause a ZeroDivisionError in the epoch loop).
- Decouple interval checkpoint saving from the NaN validation-skip
  sentinel: only the "is this the best model" comparison needs a real
  metric, so interval checkpoints now save on schedule even during
  epochs where validation was skipped.
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.

Add validation options to fine tuning

2 participants