Metadata-Version: 2.4
Name: h2ofm
Version: 0.43.1
Summary: H2O.ai Foundation Models — standalone inference
Author: H2O.ai
License-Expression: Apache-2.0
Project-URL: Homepage, https://h2oai.com/
Keywords: foundation models,time series,forecasting,tabular data,classification,regression
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: THIRD_PARTY.md
Requires-Dist: numpy>=1.26
Requires-Dist: pandas>=2.0
Requires-Dist: torch<3,>=2.10
Requires-Dist: safetensors>=0.6.2
Requires-Dist: huggingface-hub>=0.34
Requires-Dist: scikit-learn>=1.3
Dynamic: license-file

# h2ofm — H2O.ai Foundation Models

Standalone inference for H2O.ai foundation models. Python 3.12+; CPU and
CUDA.

- [TimeH2O](#timeh2o): time-series forecasting.
- [TabH2O](#tabh2o): tabular classification and regression.

```bash
pip install h2ofm
```

## TimeH2O

### Quick Start

```python
import numpy as np
from h2ofm import TimeH2O

model = TimeH2O.from_pretrained("h2oai/timeh2o-v1")
forecast = model.forecast(np.sin(np.arange(200) / 10), horizon=24)

forecast.point  # (24,), median forecast; also forecast.median
forecast.quantiles  # (24, 9), default levels 0.1 through 0.9
forecast.quantile(0.9)  # (24,)
```

Loading defaults to `device="auto"` (CUDA if available, otherwise CPU).
Set `batch_size` at load time (default 256): it counts target and covariate
rows, not series. Checkpoints without cross-variate attention drop covariate
rows first, so there only targets count. Checkpoint settings are available
through `model.config`.

### Array Forecasts

`forecast(context, horizon=...)` returns a `Forecast` with CPU NumPy arrays:

| Input shape          | `point` shape        | `quantiles` shape            |
| -------------------- | -------------------- | ---------------------------- |
| `(history,)`         | `(horizon,)`         | `(horizon, levels)`          |
| `(targets, history)` | `(targets, horizon)` | `(targets, horizon, levels)` |

`forecast_many(contexts, horizon=...)` forecasts several independent series
in one pass. It takes a list of series, with possibly different history
lengths, and returns one `Forecast` per series in input order:

```python
import numpy as np
from h2ofm import TimeH2O

contexts = [np.sin(np.arange(n) / 10) for n in (200, 150, 300)]

model = TimeH2O.from_pretrained("h2oai/timeh2o-v1")
forecasts = model.forecast_many(contexts, horizon=24)

len(forecasts)  # 3
forecasts[0].point  # (24,)
forecasts[0].quantiles  # (24, 9)
```

For array inputs, the first axis is the batch: a 2D array batches univariate
series; a 3D array batches multi-target series.

`quantile_levels` selects output levels (default 0.1 through 0.9) and their
order on the last axis.

`forecast.point` and `forecast.median` return the same median array.
`forecast.mean` approximates the mean from the full trained quantile grid,
independently of the requested `quantile_levels`. It has the same shape as the
median. Clipping and rounding apply to each output after the mean is calculated.
The mean estimate can be inaccurate, especially for distributions with heavy tails.

NaN marks missing observations; all-missing targets use a zero-valued cold start.

Covariate arguments:

- `past_covariates`: values observed over the **history** only, shaped
  `(history,)` or `(covariates, history)`. Ignored by checkpoints without
  past-covariate support.
- `future_covariates`: known values spanning **history + horizon**, shaped
  `(history + horizon,)` or `(covariates, history + horizon)`.
- For `forecast_many`, pass one covariate entry per series, using `None`
  where absent.
- A covariate row is numeric when its dtype is numeric and not boolean.
  Rows of any other dtype (strings, objects, booleans, `pd.Categorical`) are
  categorical and encoded exactly as the matching `forecast_df` column, with
  `None`/NaN as a missing label. Pass mixed covariates as a list of rows, e.g.
  `[prices, holiday_names]`.

Checkpoints without cross-variate attention ignore covariates with a warning.

### Dataframe Forecasts

Generate 100 days of two series with different periods and forecast the
next 24 days:

```python
import numpy as np
import pandas as pd

from h2ofm import TimeH2O

history, horizon = 100, 24
days = np.arange(history)
dates = pd.date_range("2026-01-01", periods=len(days), freq="D")

frames = []
for item, period in [("weekly", 7), ("monthly", 30)]:
    value = np.sin(2 * np.pi * days / period)
    frames.append(pd.DataFrame({"item": item, "date": dates, "value": value}))
context = pd.concat(frames, ignore_index=True)

model = TimeH2O.from_pretrained("h2oai/timeh2o-v1")
predictions = model.forecast_df(
    context,
    horizon=horizon,
    target="value",
    id_column="item",
    time_column="date",
)
print(predictions.head())
```

`target` is one column name or a list of target column names
(default `"target"`). Without `id_column`, the frame is one series;
without `time_column`, rows stay in input order.
The time column may contain datetimes or integer values representing time
steps. Integer times are never converted to dates; forecast rows continue them
at the inferred step, or at an integer `freq`.

`context` contains only history, including trailing missing measurements or
all-missing series. An integer `horizon` generates that many future steps per
item, and every covariate is past-only.

To supply future covariates, pass a horizon frame as `horizon` instead. Target
columns in it must be absent or entirely missing. Every covariate column in the
horizon frame is future-known, even when all its horizon values are missing (a
missing categorical value is itself informative, e.g. "no holiday"); leave
past-only covariates out of it; no current checkpoint uses them. Partial
missingness is allowed, including items with no known values for a covariate.

For panels, both frames must contain the same IDs, and every item in the
horizon frame must have the same number of rows. That count sets the horizon.
Future timestamps must continue each history at its inferred frequency (or the
explicit `freq`), even without future covariates. Without time columns, rows
retain their per-item input order. Neither input frame is mutated.

Output columns: the supplied ID and time columns (or `step`, 1 to `horizon`,
when no time column is given), `target_name`, `predictions` (median), and
one column per quantile, e.g. `"0.1"`. `freq` overrides inferred frequency:
a pandas offset alias for datetimes, the integer step between time values for
an integer time column.

### Forecast Options

All three forecast methods accept:

| Option                     | Behavior                                                                                                                                                           |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `context_length`         | Shorten the checkpoint's context window.                                                                                                                           |
| `autoregressive=None`    | Use the checkpoint's default. `True` decodes beyond `max_horizon` in blocks; `False` uses one pass.                                                           |
| `quantile_levels`        | Distinct levels between 0 and 1; levels outside the trained 0.1–0.9 grid use Gaussian-tail extrapolation.                                                         |
| `flip_equivariant=True`  | Whether to ensure flip equivariance: a flipped history produces a flipped forecast. Both checkpoints below are flip-equivariant, so this costs no extra pass and `False` has no effect. |
| `clip_nonnegative=False` | Set to `True` to clamp forecasts at zero for targets with nonnegative histories. Applied after flip blending and quantile extrapolation.                                                               |
| `snap_integer=False`     | Set to `True` to round forecasts to integers (half to even) for targets with integer-valued histories. Applied last, after `clip_nonnegative`.                     |
| `patch_ensemble=True`    | On a variable-patch checkpoint, average the forecasts of every trained patch size whose window holds the series' history, one pass per size. `False` forecasts at the checkpoint's default size in one pass. Single-size checkpoints ignore it. |

### Model Checkpoints

| Name                        | Parameters | Past covariates | Future covariates | Flip equivariant | Patch ensemble |
| --------------------------- | ---------- | --------------- | ----------------- | ---------------- | -------------- |
| `h2oai/timeh2o-v1`          | 108.8M     | No              | Yes               | Yes              | Yes            |
| `h2oai/timeh2o-v1-tiny`     | 5.8M       | No              | No                | Yes              | No             |

The targets of a multi-target series are forecast in parallel, each from
its own history, as if they were separate independent series.

Past and future covariates are always validated, but a checkpoint only
uses the kinds it supports. The others are ignored with a warning.

## TabH2O

TabH2O predicts the rows of a test table from the labeled rows of a training
table in one forward pass (in-context learning); nothing is trained or tuned.

### Quick Start

```python
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

from h2ofm import TabH2O

X, y = load_breast_cancer(return_X_y=True, as_frame=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

model = TabH2O.from_pretrained("h2oai/tabh2o-v1.1")
result = model.classify(X_train, y_train, X_test)

result.probabilities  # (n_test, 2), columns follow result.classes
result.labels  # (n_test,), the most probable class
```

`regress` predicts the distribution of a numeric target:

```python
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split

from h2ofm import TabH2O

X, y = load_diabetes(return_X_y=True, as_frame=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

model = TabH2O.from_pretrained("h2oai/tabh2o-v1.1")
result = model.regress(X_train, y_train, X_test)

result.mean  # (n_test,)
result.median  # (n_test,)
result.quantiles  # (n_test, 9), default levels 0.1 through 0.9
result.quantile(0.9)  # (n_test,)
```

Loading defaults to `device="auto"` (CUDA if available, otherwise CPU).
Weights are float32. On CUDA, tables with at least 1,024 training rows or 60
features run in float16 mixed precision; on CPU everything runs in float32.
Reuse a loaded model for every call; nothing is cached between calls.
Checkpoint settings are available through `model.config`.

### Inputs

- `X_train` and `X_test` are DataFrames with the same columns in the same
  order, or 2D arrays shaped `(rows, features)`.
- Numeric columns may contain NaN for missing values, which are replaced by
  the training mean. String, object, categorical and boolean columns are
  categorical; missing and unseen categories are allowed. Other column types,
  such as datetimes, raise a `TypeError`: convert them to numbers or strings
  first.
- Columns with a single distinct training value, or with no observed
  training value, are ignored.
- `y_train` holds one value per training row: labels of any sortable type
  for `classify`, finite numbers for `regress`.
- Inputs are never modified. Predictions are deterministic: the ensemble is
  drawn from `random_state`, so the same `random_state` and inputs give the
  same predictions.

### Prediction Options

| Option                    | Method     | Behavior                                                                                                                                                  |
| ------------------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `n_estimators=8`          | both       | Ensemble members, averaged. Members alternate between no normalization and Yeo-Johnson, each pair sharing a feature order; every member flips its own feature signs. A table with H informative features runs at most 2H members. |
| `softmax_temperature=1.0` | `classify` | Divides the averaged logits; lower values give sharper probabilities. No effect above `config.max_classes` classes, which use a class hierarchy instead. |
| `quantile_levels`         | `regress`  | Distinct levels within the predicted grid (0.001 to 0.999), returned in the requested order; default 0.1 through 0.9.                                    |
| `random_state=42`         | both       | Draws the members' feature orders and sign flips; an integer from 0 to 2**32 - 1.                                                                         |

### Model Checkpoints

| Name                | Parameters | Tasks                      | Classes                                      |
| ------------------- | ---------- | -------------------------- | -------------------------------------------- |
| `h2oai/tabh2o-v1.1` | 29M        | Classification, regression | 10 natively; more through a class hierarchy |

Memory and time grow with the number of rows and features. On an NVIDIA L4,
30,000 training rows with 100 features take about 23 seconds and 3 GiB of
GPU memory to predict 1,000 rows.

## License

Apache-2.0; see the `LICENSE` file in the distribution. Upstream attribution:
`THIRD_PARTY.md`, shipped alongside it.
Model weights are downloaded and licensed separately.
