tabpfn-extensions Bayesian optimization example into a step-by-step notebook. We optimize the 4D Rosenbrock benchmark, compare TabPFN-driven search against random search under the same evaluation budget, and show how propose_next_point() uses the predictive distribution from TabPFN to compute Expected Improvement (EI).
A single run tells you very little — the starting design alone can decide the outcome. So we repeat the whole experiment 5 times with different random inits and report the mean with a min–max band.
Relevant resources:
tabpfn-extensionsrepository- Bayesian optimization example script in
tabpfn-extensions PFNs4BOpaper / reference implementation- TabPFN repo
Setup
Install the full TabPFN package plus the Bayesian optimization extras fromtabpfn-extensions.
This example uses the local PyTorch-backed TabPFN implementation because the optimizer refines candidates with gradients (differentiable_input=True).
The Optimization Problem
Rosenbrock-4 is a four-dimensional benchmark with a narrow, curved valley: easy to fall into, hard to walk along. Its optimum is0.0 at (1, 1, 1, 1), and random search burns most of its budget far outside the valley.
The TabPFN surrogate predicts a full bar distribution over the objective value. propose_next_point() uses that predictive distribution to compute Expected Improvement, then refines the most promising candidates with gradient ascent on the acquisition function itself.
Two details worth calling out:
negate=Trueturns the minimization benchmark into a maximization problem, which is what EI expects;optimal_valuefollows the sign.- The optimizer searches the unit cube
[0, 1]^4, but Rosenbrock lives on[-5, 10]^4, so every candidate is mapped onto the problem’s own bounds before evaluation.
Build the TabPFN Surrogate
The critical switch isdifferentiable_input=True.
That flag keeps gradients flowing from the acquisition value back into the candidate coordinates during refinement. We use a single estimator to stay close to the upstream example and keep runtime short on CPU.
Each repeat gets its own surrogate, seeded with that repeat’s index, so the runs are independent.
Run Bayesian Optimization
Seed with random points, then let TabPFN propose the next evaluation point. Each iteration fits TabPFN on all observed evaluations so far, screens a random candidate pool with Expected Improvement, and refines the top candidates by gradient ascent before returning the next point to evaluate. We run that loopN_SEEDS = 5 times. Within a repeat, both methods start from the same N_INIT random evaluations, so the two curves can only diverge once the acquisition function takes over.
Compare Against Random Search
Same objective, same budget, same starting points — only the choice of the next point differs. Rosenbrock values span several orders of magnitude, so we report the gap to the optimum (optimum - best so far) rather than the raw objective. Lower is better.
Takeaways
tabpfn-extensionsalready provides the Bayesian Optimization loop primitive:propose_next_point()- On Rosenbrock-4, TabPFN with Bayesian Optimization should close the gap to the optimum faster than random search under the same evaluation budget.
- For more background, start with the upstream example and the
tabpfn-extensionsrepo.