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

# Hosted ML models

> Create models, append training records, train versions, and use them in simulation

Hosted ML models live in the Hardwave cloud. Each model owns its training records and keeps a history of trained versions. When you append new records the model becomes **stale** until you retrain; retraining creates a new version rather than a new model.

Requires a Builder or Crew plan with ML train credits.

## Create a model

```python theme={null}
import hardwave.premium

hardwave.premium.configure(
    organization_id="<your-org-uuid>",
    secret_key=open("hardwave_private.pem").read(),
)

model = hardwave.premium.create_model(
    "dc-motor-from-bench",
    component_class="DCMotor",
    input_ports=["voltage", "load_torque"],
    output_ports=["angular_velocity", "winding_temp"],
)
model_id = model["id"]
```

You can also create models in the dashboard under **Models**.

## Append training records

```python theme={null}
import time

records = []
for i in range(80):
    v = 6.0 + (i % 10) * 0.6
    load = 0.1 + (i % 5) * 0.05
    records.append({
        "timestamp": time.time() + i,
        "inputs": {"voltage": v, "load_torque": load},
        "outputs": {
            "angular_velocity": v * 15.0 - load * 40.0,
            "winding_temp": 25.0 + v * 1.2 + load * 8.0,
        },
        "source": "user",
    })

hardwave.premium.append_records(model_id, records)
```

You can also push measurements from a simulation run. After `engine.run(...)`, map `component.export_telemetry()` into the same record shape and call `append_records`.

## Train / retrain

```python theme={null}
job = hardwave.premium.train_model(model_id, min_samples=50)
print(job["status"], job.get("version"))

# Poll until ready
import time
from hardwave.premium.client import PremiumClient

client = PremiumClient(
    hardwave.premium._organization_id,
    hardwave.premium._secret_key,
    hardwave.premium._server_url,
)
while True:
    meta = hardwave.premium.get_model(model_id)
    print(meta["status"], meta.get("up_to_date"), meta.get("current_version"))
    if meta["status"] == "ready":
        break
    if meta["status"] == "failed":
        raise RuntimeError(meta.get("error_message"))
    time.sleep(3)
```

Each successful train creates a new **version**. The dashboard shows version history and whether the model is **up to date** or **stale** relative to its records.

```python theme={null}
versions = hardwave.premium.list_versions(model_id)
```

## Use the model

```python theme={null}
# Register ready models as ML_* components
hardwave.premium.sync()

# Or attach to an existing component instance
motor = ...  # your Component
hardwave.premium.attach_model(motor, model_id)
```

Hosted inference is metered as a premium solve.

## Workflow

```
Create model → append records → train → (optional) append more → retrain (new version)
```

1. **Create** a model with port schema.
2. **Append** measurements (API, dashboard, or sim export).
3. **Train** (metered). Artifacts are stored as a versioned ONNX solver.
4. **Use** via `sync()` / `attach_model`.
5. When data changes, the model is **stale** until you retrain.

See [Solvers](/simulation/solvers) for other solver types, and [Premium](/premium) for authentication.
