Skip to main content
The Embeddings extension extracts latent feature representations (embeddings) from TabPFN models. These dense vectors capture the representations learned by TabPFN’s transformer and can be reused for downstream tasks such as clustering, search, visualization, meta-learning, or as features for a simpler model. TabPFNEmbedding is a scikit-learn style transformer with the familiar fit / fit_transform / transform API. It supports two extraction modes:
  • Out-of-fold embeddings (n_fold >= 2, recommended) — robust, leakage-free training-set embeddings extracted via K-fold cross-validation. These generalize better and give stronger downstream performance.
  • Vanilla embeddings (n_fold=0) — a single model is trained on the full dataset and used for everything; cheaper, but the training embeddings leak label information.
Embeddings require the full local tabpfn package — they expose internal model representations that the tabpfn-client cloud backend does not provide. Passing a client model raises a TypeError.

Getting Started

The embedding module ships in the base tabpfn-extensions package (no extra needed). Install it alongside the local tabpfn engine:

The Interface

TabPFNEmbedding follows the scikit-learn transformer contract, and the method you call depends on whose embeddings you want:
transform always runs through the final full-data model. It never returns cached training embeddings, even if X happens to equal the training set — so for leakage-free training embeddings, always use fit_transform (or read the train_embeddings_ attribute after fit).
Pass a configured TabPFN model via the model= parameter. Use a classifier or regressor depending on your task — the examples below show both. With n_fold >= 2, the training data is split into K folds; a fresh model is trained on each fold and used to embed its held-out partition. The out-of-fold (OOF) embeddings are reassembled into the original sample order, and a final model is refit on the full training set to embed unseen data.
Why prefer out-of-fold embeddings? Vanilla embeddings use a single model to embed the training and test rows. The problem with this approach is that the training rows contain target information, the test rows do not. This introduces the risk of information leakage. OOF embeddings break this leakage: every training point is embedded by a model that never saw it, so the training embeddings match the statistics of the held-out embeddings produced by transform. This is the robust variant introduced in “A Closer Look at TabPFN v2: Strength, Limitation, and Extension” (arXiv:2502.17361), and larger n_fold values yield more robust embeddings. In practice this lifts downstream performance: the get_embeddings.py example compares a baseline linear model, vanilla TabPFN embeddings, and K-fold embeddings on the same data — the K-fold embeddings come out ahead for both classification accuracy and regression R². Classifiers use StratifiedKFold and regressors use KFold. Set shuffle=True (with an optional random_state) to shuffle the split. n_fold=1 is invalid — use 0 for vanilla or >= 2 for cross-validation.

2. Vanilla embeddings

With n_fold=0, a single model is trained on the entire training set and reused for both training and unseen data. This is cheaper (one fit instead of K + 1) and fine when you only need embeddings for unseen data via transform, but avoid it for training-set embeddings you plan to feed into a downstream model — see the leakage caveat above.
Output shape. Both fit_transform and transform return a 3D array of shape (n_estimators, n_samples, embed_dim) — one embedding matrix per ensemble member. This is not a drop-in 2D input for an sklearn Pipeline. Select a single member (embeddings[0]) or aggregate across axis=0 before passing the result to a downstream estimator.

What the Embeddings Capture

To see what the transformer actually adds, hold the projection fixed and change only the representation. PCA can only rotate and rescale the space it is handed, so whatever separation shows up in two components was already present in the input. Below are scikit-learn’s 8x8 handwritten digits (load_digits: 1,797 samples, 64 pixel features, 10 classes), projected onto their first two principal components twice. On the left, straight from the raw pixels. On the right, from TabPFN’s 512-dimensional out-of-fold embeddings of the same rows. PCA of raw digit pixels compared with PCA of TabPFN embeddings Both panels are the same linear projection of the same 1,797 digits; only the input representation differs. Axis units are arbitrary and each panel is standardized, so the two are directly comparable.
Reading the panels. In pixel space the ten digits collapse into one cloud. Only 0, 4 and 6 drift to the edges; 1, 5, 7 and 8 are interleaved in the middle with no boundary between them, which is why a linear model on raw pixels struggles. On the embeddings the same two components pull 3, 2, 0, 6, 4 and 9 apart into distinct regions with clear whitespace between them, and the residual crowding is confined to the 1/7/5/8 band. Two linear dimensions out of 512 are enough to expose most of the class structure, because the transformer has already done the work that PCA cannot do on its own.
This is a supervised-versus-unsupervised comparison. PCA on pixels sees only pixels; TabPFN’s encoder is conditioned on labeled rows, so its embedding space is organized around the target rather than around pixel variance. That is the whole point of using it as a feature extractor, but it does mean the figure is not a like-for-like dimensionality-reduction benchmark.
This separability is the practical payoff. It is the same property that lets a plain linear model on top of the embeddings do well, as in the next section.

Using Embeddings as Features

A common pattern is to use TabPFN embeddings as features for a lightweight downstream model. Because the embeddings are 3D, select an ensemble member (embeddings[0]) to get a 2D feature matrix.

Parameters

After fitting, two attributes are available: model_ (the fitted full-data model) and train_embeddings_ (the training-set embeddings, OOF when n_fold >= 2).
Migration. The old get_embeddings(X_train, y_train, X, data_source=...) method and the tabpfn_clf / tabpfn_reg constructor arguments are deprecated. Use model= together with fit_transform (training, OOF) and transform (unseen data) instead.

Example Script

Full runnable example for classification and regression.

Google Colab Example

Check out our Google Colab for a demo.