> For the complete documentation index, see [llms.txt](https://gilad-rubin.gitbook.io/hypster/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gilad-rubin.gitbook.io/hypster/reference/optuna-hpo.md).

# Optuna HPO API

Install Optuna support:

{% code overflow="wrap" %}

```bash
uv add 'hypster[optuna]'
```

{% endcode %}

Public imports:

{% code overflow="wrap" %}

```python
from hypster.hpo.optuna import suggest_values
from hypster.hpo.types import HpoCategorical, HpoFloat, HpoInt
```

{% endcode %}

## suggest\_values

{% code overflow="wrap" %}

```python
suggest_values(trial, config, **kwargs) -> dict
```

{% endcode %}

Runs `config` with the regular `HP` backed by a trial value provider (`hypster.hpo.TrialValueProvider`) and returns a `values` dictionary that can be passed to `instantiate()`. Both `suggest_values` and `TrialValueProvider` are importable from `hypster.hpo` directly. Suggested values pass the same validation as explicit values. The provider mechanism (`ValueProvider` in `hypster.hp`) is internal API; `TrialValueProvider` is its public Optuna implementation.

{% code overflow="wrap" %}

```python
values = suggest_values(trial, model_config)
cfg = instantiate(model_config, values=values)
```

{% endcode %}

The adapter is branch-aware. It only suggests parameters reached by the sampled execution path.

For numeric suggestions, `min` and `max` on the `hp.int` or `hp.float` call define the Optuna search range. If either bound is omitted, the parameter default is used for that missing bound. If both are omitted, the Optuna suggestion collapses to the default value.

## HpoInt

{% code overflow="wrap" %}

```python
HpoInt(
    step=None,
    scale="linear",
    base=10.0,
    include_max=True,
)
```

{% endcode %}

| Field         | Meaning                                                                                             |
| ------------- | --------------------------------------------------------------------------------------------------- |
| `step`        | Quantization step passed to `trial.suggest_int`.                                                    |
| `scale`       | `"linear"` or `"log"`, passed as Optuna's `log` flag.                                               |
| `base`        | Must remain `10.0`; custom bases are rejected because Optuna `suggest_int()` has no base parameter. |
| `include_max` | When `False`, the Optuna high bound is reduced by `step` or `1`.                                    |

## HpoFloat

{% code overflow="wrap" %}

```python
HpoFloat(
    step=None,
    scale="linear",
    base=10.0,
    distribution=None,
    center=None,
    spread=None,
)
```

{% endcode %}

| Field              | Meaning                                                                                                                                              |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `step`             | Quantization step passed to `trial.suggest_float`.                                                                                                   |
| `scale`            | `"linear"` or `"log"`, passed as Optuna's `log` flag when `distribution` is not set.                                                                 |
| `base`             | Must remain `10.0`; custom bases are rejected because Optuna `suggest_float()` has no base parameter.                                                |
| `distribution`     | `None` and `"uniform"` use non-log `suggest_float()`. `"loguniform"` uses `suggest_float(..., log=True)`. `"normal"` and `"lognormal"` are rejected. |
| `center`, `spread` | Rejected by the Optuna adapter because they only make sense for normal/lognormal distributions.                                                      |

If `distribution="loguniform"`, the adapter uses Optuna's log sampling even if `scale` is left at its default.

## HpoCategorical

{% code overflow="wrap" %}

```python
HpoCategorical(ordered=False, weights=None)
```

{% endcode %}

The current Optuna adapter uses `trial.suggest_categorical()` for `hp.select`. `ordered=True` and `weights=...` are rejected because Optuna categorical suggestions cannot express ordered or weighted categorical semantics.

## Supported HP Calls

| HP call     | Optuna behavior                                           |
| ----------- | --------------------------------------------------------- |
| `hp.int`    | `trial.suggest_int(path, low, high, step=..., log=...)`   |
| `hp.float`  | `trial.suggest_float(path, low, high, step=..., log=...)` |
| `hp.select` | `trial.suggest_categorical(path, keys)`                   |
| `hp.nest`   | Prefixes child parameter paths.                           |

Parameter kinds without an Optuna mapping — `hp.bool`, `hp.text`, `multi_int`, `multi_float`, `multi_text`, `multi_bool`, `multi_select`, `hp.rules`, and `hp.schema` — are not tuned: during `suggest_values()` they keep their defaults (validated as usual) and are not part of the returned values dict.

Explicit child-local overrides passed with `hp.nest(child, name="child", values=...)` are validated before `suggest_values()` returns. Unknown or unreachable child keys raise instead of being silently ignored.

## Nullable Numeric Values

`allow_none=True` is not supported for HPO numeric suggestions. Model nullable search choices as categoricals, then branch to numeric parameters when needed.

## Invalid HPO Specs

`suggest_values()` raises `ValueError` when a backend-agnostic HPO spec asks for semantics that Optuna cannot represent.

{% code overflow="wrap" %}

```python
from hypster import HP
from hypster.hpo.optuna import suggest_values
from hypster.hpo.types import HpoCategorical, HpoFloat


def normal_float_config(hp: HP):
    return hp.float(
        0.1,
        name="dropout",
        min=0.0,
        max=1.0,
        hpo_spec=HpoFloat(distribution="normal", center=0.2, spread=0.05),
    )


def weighted_choice_config(hp: HP):
    return hp.select(
        ["small", "large"],
        name="model",
        hpo_spec=HpoCategorical(weights=[0.8, 0.2]),
    )
```

{% endcode %}

Both fail during `suggest_values(trial, ...)` before a values dictionary is returned, with messages naming the exact unsupported field:

{% code overflow="wrap" %}

```
Parameter 'dropout': HpoFloat(center=..., spread=...) is only meaningful for normal/lognormal distributions, which are not supported by the Optuna suggest_float adapter.
Parameter 'model': HpoCategorical(weights=...) is not supported by the Optuna suggest_categorical adapter.
```

{% endcode %}

Optuna itself also constrains log-scale steps: `HpoInt(scale="log")` only supports `step=1` (the adapter applies that automatically and rejects any other step), and `HpoFloat(scale="log")` cannot be combined with `step=` at all.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://gilad-rubin.gitbook.io/hypster/reference/optuna-hpo.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
