TabICL
TabICL is a tabular foundation model that uses column-then-row attention to scale in-context learning to large tables. See how it works and when to use it.
Overview
TabICL is a tabular foundation model that performs in-context learning on tables much larger than the first generation of such models could handle. You give it labeled rows and unlabeled rows. It reads them in one forward pass and predicts the labels of the unlabeled rows, with no training on your table. Its main idea is to split the attention work into stages: first it summarizes each column, then it turns each row into one compact vector, and only then does it run in-context learning over those row vectors.
This staged design is what lets it scale. A standard transformer that treats every cell as a token pays a heavy price as the table grows, because attention cost rises quickly with the number of tokens. TabICL reduces each row to a single embedding before the expensive step, so the final stage works on one token per row instead of one per cell. The result is a model that stays practical for tables with many thousands of rows, while keeping the main benefit of TabPFN: no per-dataset tuning.
What it is
TabICL is a pre-trained transformer-based model for tabular classification, designed around in-context learning, often shortened to ICL. The "in-context" part means the training rows are placed in the input as examples, and the model infers the rule from them on the fly. No weights change when you use it on your data.
Key properties:
- It is pre-trained once on a very large collection of synthetic tables, then frozen.
- It has a three-stage architecture: column-wise embedding, row-wise interaction, and dataset-wise in-context learning.
- It is built to scale to larger numbers of rows than earlier in-context tabular models.
- It is exposed through a scikit-learn style interface with
fitandpredict. - It treats rows as exchangeable and is designed so that shuffling the order of rows does not change its answers in a meaningful way.
Everyday analogy
Imagine a manager who must compare 50,000 job candidates. Reading every line of every resume in full for every decision is too slow. A better workflow is to first have an assistant write a one-line summary of each candidate, based on how each attribute compares with the rest of the pool. The manager then compares candidates using the one-line summaries. TabICL works this way. The column stage learns how each attribute is distributed in the pool. The row stage writes a summary vector per candidate. The final stage compares summaries and decides.
Where it came from
TabICL grew out of a clear need. The first in-context tabular models, led by TabPFN, proved that a transformer pre-trained on synthetic tables can match strong baselines on small data. But they were limited in size, because cell-level attention does not scale. Researchers asked how to keep the in-context approach while handling large tables.
Milestones, by name and year:
- "Transformers Can Do Bayesian Inference" (2021) introduced the prior-data fitted network idea that underlies this family.
- "TabPFN: A Transformer That Solves Small Tabular Classification Problems in a Second" (2022) showed the approach on small classification tasks.
- "TabICL: A Tabular Foundation Model for In-Context Learning on Large Data" (2025) introduced the column-then-row design and showed that in-context learning can be extended to much larger tables.
- Work on set-based encoders, such as the Set Transformer (2019), supplied building blocks for summarizing columns of variable size, and the Perceiver family supplied the idea of using a small set of latent tokens to compress large inputs. See Perceiver IO.
- Earlier tabular deep models, including SAINT and FT-Transformer, explored attention across rows and columns but were trained per dataset.
The general trend is clear. Each generation keeps the same recipe, pre-training on synthetic tasks plus in-context prediction, and attacks one weakness: first the scale, then the semantics, as in TabSTAR. Background on the research direction is at /model/research.
How it works
TabICL reads a table in three stages. This section explains each stage and why it exists.
The big picture
A table has n rows and d columns. A naive transformer would create n * d tokens, one per cell, and then let all of them attend to each other. Attention cost grows with the square of the token count, so this becomes very expensive. TabICL avoids that by attending along one axis at a time and by shrinking the representation before the heavy stage.
| Stage | Axis of attention | Output | Why it exists |
|---|---|---|---|
| 1. Column-wise embedding | Across the rows of one column | One embedding per cell, aware of its column's distribution | Understand each attribute on its own terms |
| 2. Row-wise interaction | Across the columns of one row | One vector per row | Combine attributes into a row summary |
| 3. Dataset-wise ICL | Across rows | Predictions for query rows | Learn the label rule from labeled rows |
Stage 1: Column-wise embedding
Each column is processed separately. For one column, the model looks at all of its values across the rows and builds an embedding for each cell that reflects where the value sits in that column's distribution. For example, the value 52 means something different in a column of ages than in a column of temperatures.
The encoder used here must handle a column of any length and must not depend on row order. A set-based transformer is a natural choice, since it treats its input as an unordered set. It uses a small number of learned "inducing" points to summarize the column, which keeps the cost close to linear in the number of rows.
Analogy: before comparing candidates, an assistant learns what a "typical" and an "extreme" value look like for each attribute, such as years of experience, so that raw values can be turned into meaningful positions.
Stage 2: Row-wise interaction
Now each row has d cell embeddings. A transformer attends across these d embeddings within the row. Special learned tokens, similar to a class token in vision transformers, collect the information and produce a single fixed-size vector for the row. Because d is usually much smaller than n, this stage is cheap compared with attending across rows.
A subtle point: the columns have no natural order, and different tables have different numbers of columns. The design therefore has to avoid learning a fixed meaning for "column position 3". Positional information is handled in a way that keeps the model flexible across tables, for example by randomizing or by using identifiers that do not carry fixed meaning.
Analogy: the assistant now writes a one-paragraph summary of each candidate, based on all their attributes together, such as "strong experience but short tenure".
Stage 3: Dataset-wise in-context learning
The row vectors from stage 2 are the tokens for the final transformer. The labeled rows get their labels embedded and added to their vectors. The query rows have no label information. The transformer lets query rows attend to labeled rows, so each query row gathers information from similar labeled rows. A prediction head then outputs class probabilities.
This is the same mechanism as in TabPFN, but over n row tokens rather than n * d cell tokens. That one change is what makes much larger contexts feasible.
Pre-training
Pre-training uses synthetic datasets drawn from a prior, as in earlier prior-data fitted networks. The generator produces tables from random structural causal models, and may include tree-based structure so that the model has seen the kinds of axis-aligned splits that tree ensembles like to exploit. Data sizes vary, so the model learns to work with both small and large contexts. A curriculum that starts with small tables and moves to larger ones is a common way to make training stable and cheaper.
Analogy: a pilot who trains first on short simple flights and later on long complex ones learns faster than one who is thrown into the hardest case on day one. See Curriculum learning.
Inference and ensembling
At inference time, the model takes the labeled rows and the query rows, and runs the three stages. Practical systems average several runs that differ in feature order, in column transforms, and in class label permutation. This reduces the variance that comes from the lack of a canonical column order. The cost grows with the number of runs, so you pick a number that balances quality and speed.
For very large tables, some implementations use caching: the column and row stages for the context rows can be computed once and reused for different batches of queries. This makes repeated prediction on the same context much cheaper, which is useful in serving.
Why compressing rows helps
There is an intuition for why one vector per row is enough. For most prediction tasks, the model does not need every raw cell at the final stage. It needs the part of the row that matters for similarity and for the label. Stage 2 learns to keep that information and to drop the rest. If compression were too lossy, accuracy would fall. In practice, the design reaches accuracy close to that of heavier cell-level models on many benchmarks, with a large saving in time and memory.
Key concepts and terms
| Term | Plain meaning |
|---|---|
| In-context learning (ICL) | Learning a task from examples placed in the input, with no weight updates |
| Column-wise embedding | A representation of each cell that depends on its whole column |
| Row-wise interaction | Attention across the columns of one row to build a row vector |
| Dataset-wise ICL | Attention across rows to link query rows to labeled rows |
| Set Transformer | A transformer that handles unordered sets of any size |
| Inducing points | A small set of learned vectors that summarize a large input |
| Class token | A special token that collects a summary of a sequence |
| Context | The labeled rows given to the model |
| Query | A row whose label is to be predicted |
| Synthetic prior | The generator of random tables used in pre-training |
| Structural causal model | A random graph of variables where each is a noisy function of its parents |
| Permutation invariance | Output does not change when the input order changes |
| Feature order ensemble | Averaging predictions across different column orders |
| KV cache | Stored intermediate results that avoid recomputation for a fixed context |
Related ideas appear in Axial attention, which also attends along one axis at a time, and in Few-shot learning, which describes the broader class of learn-from-a-few-examples methods.
A worked example
Basic usage
The typical interface looks like any other scikit-learn classifier.
import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, log_loss
from tabicl import TabICLClassifier
X, y = make_classification(
n_samples=20000, n_features=30, n_informative=12,
n_redundant=6, n_classes=3, random_state=0,
)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, random_state=0, stratify=y
)
clf = TabICLClassifier()
clf.fit(X_train, y_train) # stores context, may precompute row embeddings
proba = clf.predict_proba(X_test)
print("accuracy:", accuracy_score(y_test, proba.argmax(1)))
print("log loss:", log_loss(y_test, proba))
The table here has fifteen thousand training rows, a size that would be heavy for a cell-level in-context model. The staged design is what makes it reasonable.
Tracing the three stages by hand
Take a tiny table of four rows and two columns. The target is binary.
| Row | age | income | label |
|---|---|---|---|
| 1 | 25 | 30 | 0 |
| 2 | 35 | 40 | 0 |
| 3 | 55 | 90 | 1 |
| 4 | 60 | 95 | 1 |
| Q | 58 | 88 | ? |
Stage 1 looks at the age column: values 25, 35, 55, 60, 58. It learns that 58 sits near the top of the distribution. It does the same for income: 88 sits near the top as well. Each cell now carries a "position in my column" signal, not only the raw number.
Stage 2 looks at row Q: it has a high-age embedding and a high-income embedding. The row transformer combines them and writes a row vector that means roughly "high on both attributes".
Stage 3 compares the row vector of Q with those of rows 1 to 4. Rows 3 and 4 are close, rows 1 and 2 are far. The labels of rows 3 and 4 are both 1, so the head outputs a high probability of class 1 for Q. The real model learns this behavior implicitly from its pre-training. There is no hand-written rule.
Comparing with boosting on a large table
import time
import xgboost as xgb
t0 = time.time()
booster = xgb.XGBClassifier(n_estimators=400, max_depth=6, learning_rate=0.1,
tree_method="hist")
booster.fit(X_train, y_train)
t_boost = time.time() - t0
acc_boost = accuracy_score(y_test, booster.predict(X_test))
t0 = time.time()
clf = TabICLClassifier()
clf.fit(X_train, y_train)
acc_icl = accuracy_score(y_test, clf.predict(X_test))
t_icl = time.time() - t0
print(f"boosting: {acc_boost:.3f} in {t_boost:.1f}s")
print(f"tabicl: {acc_icl:.3f} in {t_icl:.1f}s")
Do not read too much into a single synthetic run. The exercise shows the right way to compare: same split, same metric, wall-clock time, and ideally repeated over several seeds and real datasets. Remember to count tuning time for boosting if you tune it. See XGBoost, LightGBM and CatBoost for the usual baselines.
Using it with a pipeline
from sklearn.pipeline import make_pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OrdinalEncoder
import pandas as pd
cat_cols = ["country", "device"]
num_cols = ["age", "sessions", "spend"]
pre = ColumnTransformer([
("cat", OrdinalEncoder(handle_unknown="use_encoded_value", unknown_value=-1), cat_cols),
("num", "passthrough", num_cols),
])
pipe = make_pipeline(pre, TabICLClassifier())
pipe.fit(df_train[cat_cols + num_cols], df_train["converted"])
print(pipe.predict_proba(df_test[cat_cols + num_cols])[:5])
Missing numeric values can usually be left as NaN, and missing categories can be encoded as their own code. Check the documentation of the version you use for exact support.
Why the staged design saves compute: a numeric comparison
Compare the token counts for a table with 20,000 rows and 30 columns.
| Design | Tokens in the largest attention step | Rough pairs of tokens that interact |
|---|---|---|
| Cell-level attention over all cells | 600,000 | 360 billion |
| Row-level attention after compression | 20,000 | 400 million |
| Row stage, per row | 30 | 900 |
| Column stage, per column (with inducing points) | 20,000 | Close to 20,000 times a small constant |
The row-level step still has to compare every query with every context row, but it deals with 20,000 tokens, not 600,000. The per-row and per-column steps are small because each looks at one axis only. The exact numbers depend on implementation details such as sparse patterns and memory-efficient kernels, but the order-of-magnitude gap is the reason the design exists.
What each stage learns, in plain terms
- Stage 1 learns column-level statistics without being told: whether a column is skewed, whether it has a few repeated values, where a given value falls in the ranking, and whether it has outliers.
- Stage 2 learns feature interactions: for example, that a high value in one column matters only when another column is also high.
- Stage 3 learns similarity and label propagation: which context rows are relevant to a query, and how to turn their labels into a probability.
Looking at the model this way also helps debugging. If accuracy is poor on a table with strong column interactions, suspect stage 2 and the prior. If accuracy is poor on a table with a strongly skewed column, check whether outliers are crushing the column signal and whether a transform helps. If accuracy is poor because labels are noisy, no stage can fix it, and the context may need cleaning.
An evaluation protocol that avoids common traps
- Pick the metric that matches the decision. Accuracy hides problems on imbalanced data. Use log loss for probabilities, AUC for ranking, and average precision for rare events.
- Split by group or time when rows are not independent. For example, customers with many rows should be kept in the same fold.
- Fix the context size across methods. A boosting model that sees all rows is not comparable with an in-context model that sees a sample, unless you say so.
- Run at least five seeds or five folds, and report the spread.
- Measure the whole pipeline time: loading, fit, predict, and tuning.
- Look at the largest errors by hand. Patterns in the errors often point to a data issue such as label noise or a missing feature.
from sklearn.model_selection import GroupKFold
from sklearn.metrics import log_loss
import numpy as np
gkf = GroupKFold(n_splits=5)
losses = []
for tr, te in gkf.split(X, y, groups=customer_id):
m = TabICLClassifier()
m.fit(X[tr], y[tr])
losses.append(log_loss(y[te], m.predict_proba(X[te]), labels=np.unique(y)))
print(np.mean(losses), np.std(losses))
Strengths and limitations
Strengths
- Scales to larger tables than cell-level in-context models, because attention across rows works on one token per row.
- No per-dataset training or tuning, so time to a first good model is short.
- Competitive accuracy with strong baselines on many medium and large classification tasks.
- Reusable context computations can speed up repeated predictions.
- Handles mixed numeric and categorical inputs after simple encoding.
- Permutation-friendly design reduces sensitivity to row order.
- Works on tables without column names, since it learns from value distributions.
- Good fit for pipelines that need many models across many tables.
Limitations
- Still bounded by memory and compute. Very large tables need sampling or chunking.
- The context must be kept at inference time, which makes the model artifact larger than a trained tree ensemble.
- Mostly aimed at classification. Regression support depends on the version.
- Does not read text. Free-text columns need preprocessing such as embedding with a language encoder, or a text-aware model like TabSTAR.
- Sensitive to the match between the synthetic prior and real data, as with all prior-fitted models.
- Row compression can discard fine detail needed for some tasks, such as rare interactions between many columns.
- Less interpretable than a single tree. Post-hoc tools such as SHAP help but are approximate.
- Fixed limits on the number of classes and features may apply in some versions.
How it compares with alternatives
| Method | Training on your data | Scale | Handles text | Main idea |
|---|---|---|---|---|
| TabICL | None (in-context) | Medium to large | No (preprocess text) | Column-then-row compression, then ICL |
| TabPFN | None (in-context) | Small to medium | No | Cell-level two-way attention |
| TabSTAR | Light fine-tuning | Medium | Yes | Pretrained text encoder with target-aware tokens |
| XGBoost | Yes | Small to very large | No | Gradient boosted trees |
| LightGBM | Yes | Small to very large | No | Fast histogram boosting |
| CatBoost | Yes | Small to large | Basic | Ordered boosting, native categories |
| FT-Transformer | Yes | Medium to large | No | Feature tokenizer plus transformer |
| SAINT | Yes | Medium | No | Row and column attention, contrastive pre-training |
| TabNet | Yes | Medium | No | Sequential sparse feature attention |
| Random forest | Yes | Small to large | No | Bagged decision trees |
How to choose:
- Under a few thousand rows with simple columns: try TabPFN and TabICL side by side.
- Tens of thousands of rows and a need for zero tuning: TabICL is a good first model.
- Very large tables or strict latency budgets: boosting remains the default.
- Text-heavy tables: TabSTAR or a language-model pipeline.
- Need for global feature importance and simple auditing: trees, with SHAP.
Role in tabular foundation models
TabICL shows how a tabular foundation model can be organized so that it respects the structure of tables and still scales. See /model/architecture for how these ideas connect to a full model design, and /model/benchmarks for how such models are measured.
Row and column structure
The three-stage design mirrors the two axes of a table. Stage 1 is a column operation: it looks down a column. Stage 2 is a row operation: it looks across a row. Stage 3 is a dataset operation: it looks across rows. This is a close cousin of Axial attention and of the latent-bottleneck idea in Perceiver IO. Treating the two axes differently is not an accident. Columns are heterogeneous (age is not income), while rows are samples from the same population. Different symmetries call for different attention patterns.
Mixed types
Numbers, categories and flags all reach stage 1 as values in a column. Because the column encoder learns the distribution of each column, it can tell a continuous column from one with a few distinct values. Categorical columns are usually passed as codes, and the encoder sees that the column has few unique values. This is a data-driven way to handle mixed types without hand-built rules.
No column names
TabICL, like TabPFN, is built to work without headers. It sees values and their distributions only. This makes it robust to messy or missing headers, which is common in raw exports. The price is that it cannot use the meaning of a column name. Text-aware models such as TabSTAR restore that signal. For table-level meaning, Semantic sector heads show how a label such as an industry sector can be recovered from cell values when names are absent.
Missing values
Missing cells are part of the input. The column stage can represent them with a flag or a special value in a way the model learned to read during pre-training, since the synthetic prior includes missingness. The row stage then learns to build a good summary from the observed cells. This links directly to imputation: a row vector built from partial information can be used to predict the missing cells. See Imputation networks and Masked cell modeling.
Pre-training on synthetic tables
TabICL is pre-trained on synthetic tables only, as an extension of the prior-fitted network idea. The generator includes structural causal models and tree-like functions, and varies the table size. This gives the model wide coverage and avoids using public benchmark data in training. The quality of the generator largely determines the quality of the model. For general craft on creating such data, see Synthetic data generation. A curriculum over table sizes, small to large, keeps the cost of pre-training manageable.
In-context learning
Stage 3 is the in-context learner. It treats row vectors as tokens and uses labeled rows as the prompt. This is the tabular counterpart of Few-shot learning in language models. Because the context can be large, TabICL moves in-context learning from the few-shot regime toward a many-shot regime, where the model sees thousands of examples and behaves more like a trained classifier. That bridge between prompt-style adaptation and conventional training is one of the most interesting aspects of the design.
Continual learning
The base weights are frozen, so adding new data means adding rows to the context, with no forgetting. This is a light-weight kind of continual adaptation. When you do want to update weights, for example to specialize the model on one domain, the usual continual learning toolkit applies: Experience replay, Elastic weight consolidation, and related regularizers that protect earlier knowledge while learning new tasks. Because row embeddings can be cached, a growing context can be updated incrementally, which suits streaming settings.
Imputation
Row vectors summarize partial rows, so one can train or adapt heads that predict masked cells from the row vector. Even without a dedicated head, the in-context classifier can be applied column by column: treat a column as the target, and use rows where it is known as the context. Iterating over columns gives a chained imputation scheme. This is a pre-trained alternative to per-column models and often beats simple means. Connect this with MIDAS and Denoising autoencoders for related approaches.
Anomaly detection
Row embeddings are a natural input for anomaly scoring. A row whose embedding is far from the embeddings of the context rows, or whose predicted label disagrees with its observed label, is a candidate anomaly. Distance in embedding space, k-nearest-neighbor scores, or reconstruction-style scores can all be applied on top. See Anomaly detection and Isolation forest for classical baselines to compare with. The benefit of embedding-based scoring is that the model has learned a notion of similarity that accounts for column distributions and interactions.
Sector and semantic classification
Classifying a whole table into an industry sector needs a table-level representation. The staged design gives a natural route: pool the row vectors from stage 2 (for example, by averaging or by attention pooling) to get one vector for the table, then attach a classification head. This is the structure of Semantic sector heads, which map a table-level embedding to a coarse-to-fine hierarchy of sectors. Because TabICL does not need column names, the head would learn from patterns of values such as ranges, cardinalities and correlations, which can still carry strong signals about the domain.
Practical guidance and best practices
When it is a good choice
- You have a classification problem with thousands to tens of thousands of rows.
- You want a strong model without tuning.
- You have many tables and cannot afford per-table tuning.
- You need a baseline to challenge a boosting model.
Preparing the data
- Remove identifiers and constant columns.
- Encode categories as ordinal codes. Avoid one-hot encoding of high-cardinality columns.
- Keep missing values as missing, and avoid sentinel numbers.
- Convert dates to numeric parts or elapsed time.
- Embed free text with a language encoder first, or exclude it, because the model does not read text.
- Check the class balance. For strong imbalance, evaluate with metrics such as average precision, not only accuracy.
Choosing the context
- Use as many labeled rows as fit in memory, within reason, since returns diminish.
- Use stratified sampling to keep class proportions.
- For time-dependent data, prefer recent rows and split by time.
- Remove exact duplicates, which waste context and can leak labels.
Evaluating fairly
- Use repeated cross-validation or several random seeds.
- Compare with tuned XGBoost, LightGBM or CatBoost under a fixed time budget, using a tool like Optuna for the search.
- Report both quality and total time, including tuning.
- Check calibration with a reliability plot, and apply a post-hoc fix if needed.
Serving
- Store the context with the model, and version both.
- Use caching of context computations where the library supports it.
- Batch queries to share the cost of reading the context.
- Refresh the context on a schedule, or when drift is detected.
- Monitor input distributions and prediction confidence in production.
Combining with other models
- Blend its probabilities with those of a boosting model. The two families make different errors, so a simple average often helps.
- Use it as a feature generator: feed its predicted probabilities as a feature into a downstream model, with out-of-fold predictions to avoid leakage.
- Use it as a quick screen to decide whether a problem is learnable before investing in heavy modeling.
A troubleshooting guide
| Symptom | Likely cause | What to try |
|---|---|---|
| Out-of-memory error | Context too large for the device | Subsample the context, reduce ensemble members, use a larger GPU |
| Accuracy below a simple baseline | Strong leakage in the baseline, or a broken encoding | Re-check the split, inspect category codes, remove ID columns |
| Good accuracy, poor calibration | Prior mismatch or class imbalance | Apply temperature scaling or isotonic calibration on a validation fold |
| Slow predictions | Large context recomputed on every call | Cache context computations, batch queries |
| Unstable results across runs | Random feature orders in the ensemble | Fix seeds, increase ensemble size |
| Poor results on a text-heavy table | Text columns are not understood | Embed text first, or use a text-aware model |
| Drop in production accuracy | Drift between context and live data | Refresh the context, monitor input distributions |
Using the row embeddings beyond classification
The row vectors are useful on their own. Some practical uses:
- Similar-row search. Find the nearest rows to a given row in embedding space. This helps with deduplication, with finding comparable customers, and with explaining a prediction by example.
- Clustering. Run k-means or a density-based method on the row vectors for segmentation. See Clustering and UMAP for projection to two dimensions.
- Outlier screening. Rows far from all others in embedding space deserve a manual look.
- Feature input for other models. Feed the vectors, or a reduced version of them, to a downstream model. Use out-of-fold computation to avoid leaking labels.
These uses depend on whether the library exposes the embeddings. If it does not, a similar effect can be achieved by using the predicted probabilities as a compact summary.
A note on versions and reproducibility
Models in this family are updated often. Weights, default ensemble sizes, supported row and feature limits, and supported task types change between releases. For results that others can reproduce, record the library version, the weights identifier, the random seed, the ensemble size, the preprocessing steps, and the hardware. Store the exact context rows or a hash of them. Without this, a number reported today may be impossible to reproduce next quarter.
Quick decision flow
- Is the target a class label and is the table mostly numbers and categories? If not, consider other tools.
- Does the table have fewer rows than the documented limit? If not, sample or choose boosting.
- Is there free text that matters? If yes, embed it or use TabSTAR.
- Do you need per-prediction latency in milliseconds at huge volume? If yes, prefer a compact trained model.
- Otherwise, run TabICL with defaults, compare it with a tuned booster, and keep the better or blend both.
Common mistakes
- Feeding raw text columns and expecting the model to understand them.
- Using a context that is much larger than memory allows and getting silent subsampling or errors, without checking which happened.
- One-hot encoding categorical columns with thousands of levels.
- Evaluating with a single split and over-reading small differences.
- Tuning the boosting baseline for hours while running TabICL with defaults, or the reverse, and calling the comparison fair.
- Using random splits for data with a time order, which leaks future information.
- Not shipping the context rows with the model, so predictions cannot be reproduced.
- Treating the output probabilities as calibrated without checking.
- Ignoring duplicates between the training rows and the test rows.
- Assuming the model is a regression tool when the version in use supports classification only.
- Forgetting to set random seeds, then being unable to reproduce an ensemble result.
Frequently asked questions
What is TabICL used for?
TabICL is used to predict labels for rows of a table, mostly classification, without training a model on that table. It is a good fit for medium and large tables where you want strong accuracy quickly and do not want to tune hyperparameters. It also serves as a strong baseline against which to test boosting models.
How is TabICL different from TabPFN?
Both are pre-trained on synthetic tables and use in-context learning. The main difference is the architecture. TabPFN uses attention at the cell level, which is very accurate on small tables but gets expensive as tables grow. TabICL first compresses each row into a single vector using column-wise and row-wise stages, and then runs in-context learning over rows, which allows much larger tables.
What does column-then-row attention mean?
It means the model attends along the columns first and the rows second. In the first stage, each column is processed on its own to learn what its values look like. In the second stage, the cells of one row are combined into a single vector. Only after that does the model attend across rows to link queries to labeled examples.
Does TabICL need training on my data?
No. The weights are frozen and are not updated on your table. When you call fit, the labeled rows are stored and may be pre-processed. When you call predict, the model reads the context and the query rows and returns probabilities in one pass.
Can TabICL handle missing values and categorical features?
Yes, with simple preparation. Missing values can stay as missing, and categories are passed as codes. The synthetic pre-training data includes such properties, so the model has learned to deal with them. As always, avoid sentinel values and very wide one-hot encodings.
Is TabICL better than XGBoost?
Not always. On many medium tables it is competitive and needs no tuning, which can make it the faster route to a good model. On very large tables, or where cheap serving and simple explanations matter, boosting such as XGBoost is often the better choice. The only reliable answer comes from testing both on your own data.
Does it use column names?
No. It works from values and their distributions only. This makes it robust when headers are missing or unreliable, but it cannot benefit from the meaning of the names. If names are informative, a text-aware model such as TabSTAR may do better.
Can I use TabICL for imputation or anomaly detection?
Yes, with some work. For imputation, treat each column with gaps as a target and predict missing entries from the other columns, using rows where the value is known as the context. For anomaly detection, use the row embeddings or the prediction confidence to score how unusual a row is. Both uses benefit from a mostly clean context.
How large a table can it handle?
It is designed for much larger tables than the first in-context models, reaching into the tens of thousands of rows and beyond, depending on available memory and the version. Exact limits change between releases, so check the current documentation and test with your hardware.
What is the role of synthetic data in TabICL?
Synthetic data is the only source of pre-training. Random structural causal models and tree-like functions create a huge variety of tables with known properties. This gives broad coverage, avoids privacy issues, and keeps public benchmarks out of training. The quality of the generator is a key factor in how well the model transfers to real tables.
Glossary
- Axis: One dimension of a table, either rows or columns.
- Class token: A learned token that gathers a summary of a set of tokens.
- Context: The labeled rows that act as the prompt for in-context learning.
- Embedding: A vector that represents an item such as a cell, a row or a table.
- Foundation model: A model pre-trained broadly and reused on many tasks.
- Inducing points: Learned vectors that compress a large set into a small one.
- In-context learning: Adapting to a task from examples in the input, with no weight updates.
- Latent bottleneck: A small set of vectors through which a large input is passed to cut cost.
- Many-shot: In-context learning with thousands of examples rather than a handful.
- Permutation invariance: A property where reordering the input does not change the output.
- Prior-data fitted network: A network trained on datasets sampled from a prior to approximate Bayesian prediction.
- Query row: A row without a label that the model must predict.
- Set Transformer: A transformer for unordered sets of variable size.
- Synthetic data: Artificially generated data used for training.
Summary
TabICL is a tabular foundation model that extends in-context learning to larger tables by working in three stages: it embeds each column with awareness of its distribution, compresses each row into one vector, and then runs in-context learning over row vectors. It is pre-trained only on synthetic tables, needs no training on your data, and gives strong accuracy on many medium and large classification tasks with little effort.
Its role in tabular foundation models is to show that the row and column structure of tables can be turned into an architecture that scales. It connects naturally to missing-value handling, imputation, anomaly scoring and table-level semantic labeling through its row embeddings. For related methods see TabPFN, TabSTAR and Semantic sector heads, and for the wider context see /model/research, /model/architecture and /model/benchmarks.
Related
It belongs to Related models and baselines in my stack, under Foundation models and applied ML. Others in the same group: