> ## Documentation Index
> Fetch the complete documentation index at: https://docs.outerproduct.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Reasoning Models

> Train OuterProduct reasoning models optimized over custom model families (including foundation models), hyper-parameter configurations, and metrics.  

OuterProduct optimizes reasoning model performance over the configurations specified by:

* An `hpo_space`that optionally specifies model families and hyper-parameters per family.
* An `optimizer`that optionally specifies the search strategy over the defined `hpo_space`.

When you call `fit()`, all candidate model families in the space are searched with maximum parallelization.

If there is one metric specified, the result is a single trained model representing the best configuration found.  If multiple metrics are specified, the result is the set of models along the Pareto frontier.

## Optimized Reasoning Models At Enterprise Scale

Build optimized reasoning models by tuning over model families, hyper-parameter configurations, and even multiple metrics.   The example below shows how to build a reasoning model for regression across the TabM and TabICL model families.

```python theme={null}
import outerproduct as op

op.init()
ws = op.Workspace()

train_df = ws.table("customers")

# TabM: MLP-style tabular net (https://arxiv.org/abs/2410.24210)
tabm = (
    op.ModelParamSpace(family="tabm")
    .float("lr", 1e-4, 3e-3, log=True)
    .categorical("n_blocks", [1, 2, 3, 4])
    .int("d_block", 64, 512, log=True)
)

# TabICL: tabular foundation model (https://arxiv.org/abs/2602.11139)
tabicl = (
    op.ModelParamSpace(family="tabicl")
    .int("n_estimators", 1, 32, log=True)
    .float("softmax_temperature", 0.5, 2.0)
    .categorical("average_logits", [True, False])
    .categorical("norm_methods", ["none", "power", "quantile"])
)

hpo_space = op.HPOSpace().add(tabm).add(tabicl)
model = op.reasoning.fit(
    train_df, 
	hpo_space=hpo_space,
	optimizer=op.Optimizer(kind="tpe", n_trials_per_step=5, n_steps=4),
	task=op.Regression(label_column="sales_30d"),
).wait()  
```
