Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
73750b1
refactor(rl): use the shared training progress callback directly
albcui Aug 13, 2026
d94bc20
fix(customization): stop non-step reports from erasing the metric series
albcui Aug 13, 2026
3148e23
feat(customization): accumulate a time series for every reported metric
albcui Aug 13, 2026
87dd591
fix(customization): carry sticky status_details fields across updates
albcui Aug 13, 2026
5198b65
fix(rl): report the final training step, and stop double-counting it
albcui Aug 13, 2026
db49abd
thanks CodeRabbit
albcui Aug 13, 2026
8c1f86c
refactor(customization): drop the carry-forward machinery
albcui Aug 13, 2026
a38f103
fix(customization): correct three defects in the reported payload
albcui Aug 13, 2026
6cb5a18
chore(rl): give the new progress module the header its siblings use
albcui Aug 13, 2026
9e66baa
docs(customization): stop justifying the design with an unwired GRPO …
albcui Aug 13, 2026
8fdf28f
fix(rl): make the steps_per_epoch fallback reachable, and drop a stri…
albcui Aug 13, 2026
3668407
docs(customization): keep the callback's rationale out of the reporter
albcui Aug 13, 2026
e72b354
refactor(rl): stop holding a reference the logger never reads
albcui Aug 13, 2026
73fb71e
refactor(customization)!: one naming rule for every training metric
albcui Aug 13, 2026
316a082
docs(customizer): document the metric naming rule and the series payload
albcui Aug 13, 2026
58307cc
fix(rl): bound progress reports by run length, not just val_period
albcui Aug 14, 2026
2889bf6
fix(automodel): strip the val_ prefix the recipes already applied
albcui Aug 14, 2026
934d8b1
fix(customization): discard the steps a resumed run replays
albcui Aug 14, 2026
4095302
fix(rl): report a validation pass that scores on something other than…
albcui Aug 14, 2026
a27cd5a
fix(customization): correct twelve defects across the progress report…
albcui Aug 14, 2026
f21d67e
fix(rl): derive the train report cadence from run length alone
albcui Aug 14, 2026
5d86886
update docstrings to reflect seeding mechanism
albcui Aug 14, 2026
25f30ae
refactor(customization): rename the metric-name qualifier off "namesp…
albcui Aug 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 45 additions & 6 deletions docs/customizer/manage-customization-jobs/get-job-status.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ Get detailed execution status for a customization job, including step-by-step pr
This endpoint provides granular execution details including:

- **Step-level status**: `model-and-dataset-download` → `training` → `model-upload` → `model-entity-creation`
- **Training metrics**: `step`, `epoch`, `train_loss`, `lr` (learning rate), `grad_norm`, `val_loss`
- **Training progress**: `step`, `epoch`, `max_steps`, `num_epochs`, `percentage_done`
- **Latest metric values**: one field per metric, named `<phase>_<metric>` — `train_loss`, `train_lr`, `train_grad_norm`, `val_loss`, and whatever else your backend reports
- **Metric history**: `metrics`, holding each metric as a series of `{step, epoch, value}` points
- **Progress tracking**: `downloaded_files`, `uploaded_bytes`, `progress_pct`

Which metrics appear depends on the backend and the algorithm. See [Checking Your Customization Job Metrics](/documentation/customizer-reference/tutorials/metrics) for how the names are formed.

To list jobs or get job definitions (model entity, hyperparameters, spec), use [List Active Jobs](/documentation/customizer-reference/manage-customization-jobs/list-active-jobs) instead.

</Tip>
Expand Down Expand Up @@ -146,9 +150,25 @@ curl -X GET \
"num_epochs": 2,
"step": 8,
"epoch": 1,
"percentage_done": 8,
"train_loss": 2.8918895721435547,
"lr": 4.9101714686276044e-05,
"grad_norm": 26.0
"train_lr": 4.9101714686276044e-05,
"train_grad_norm": 26.0,
"metrics": {
"train_loss": [
{ "step": 4, "epoch": 1, "value": 3.2087905406951904 },
{ "step": 8, "epoch": 1, "value": 2.8918895721435547 }
],
"val_loss": [],
"train_lr": [
{ "step": 4, "epoch": 1, "value": 4.9550857343138022e-05 },
{ "step": 8, "epoch": 1, "value": 4.9101714686276044e-05 }
],
"train_grad_norm": [
{ "step": 4, "epoch": 1, "value": 31.5 },
{ "step": 8, "epoch": 1, "value": 26.0 }
]
}
}
}
]
Expand Down Expand Up @@ -222,11 +242,30 @@ curl -X GET \
"num_epochs": 2,
"step": 94,
"epoch": 2,
"percentage_done": 100,
"train_loss": 0.3437718152999878,
"lr": 5.000000000000001e-07,
"grad_norm": 20.125,
"train_lr": 5.000000000000001e-07,
"train_grad_norm": 20.125,
"val_loss": 0.5527229905128479,
"checkpoint_path": "/var/run/scratch/job/training/checkpoints"
"checkpoint_path": "/var/run/scratch/job/training/checkpoints",
"metrics": {
"train_loss": [
{ "step": 47, "epoch": 1, "value": 1.1204545497894287 },
{ "step": 94, "epoch": 2, "value": 0.3437718152999878 }
],
"val_loss": [
{ "step": 47, "epoch": 1, "value": 0.9182837605476379 },
{ "step": 94, "epoch": 2, "value": 0.5527229905128479 }
],
"train_lr": [
{ "step": 47, "epoch": 1, "value": 2.5e-05 },
{ "step": 94, "epoch": 2, "value": 5.000000000000001e-07 }
],
"train_grad_norm": [
{ "step": 47, "epoch": 1, "value": 24.75 },
{ "step": 94, "epoch": 2, "value": 20.125 }
]
}
}
}
]
Expand Down
49 changes: 43 additions & 6 deletions docs/customizer/tutorials/metrics.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,38 @@ The time to complete this tutorial is approximately 10 minutes.

## Available Metrics

Each customization job tracks two key metrics:
A customization job tracks every numeric metric its backend reports, not a fixed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is backend the right word here? DPO and GRPO are same backend, do they report the same metrics?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The infrastructure for logging metrics is at the backend level. DPO and GRPO share the same logger, just different metrics. Previously, we were being opinionated about which metrics to report, now I'm just going to report all numeric metrics given to us. Maybe we should have an allowlist, but we can add that later. This means, once this change lands, we should more or less get GRPO metrics for free.

list. Training loss and validation loss are always among them:

- **Training Loss**: Calculated during training, logged every 10 steps (default, configurable via hyperparameters)
- **Validation Loss**: Calculated during validation, logged at each validation interval
- **Training Loss** (`train_loss`): Calculated during training, logged every 10 steps (default, configurable via hyperparameters)
- **Validation Loss** (`val_loss`): Calculated during validation, logged at each validation interval

Alongside those you will typically see `train_lr` (learning rate) and
`train_grad_norm`, plus whatever else the algorithm produces — a DPO job also
reports `train_preference_loss` and `val_accuracy`, for example.

### How Metrics Are Named

Each metric is named `<phase>_<metric>`, where the phase is `train` or `val` and
the metric keeps whatever name the training framework gave it. A metric reported
during both training and validation therefore stays separate: DPO's `accuracy`
becomes `train_accuracy` and `val_accuracy` rather than one interleaved series.

`train_loss` and `val_loss` are simply what this rule produces for a metric named
`loss`.

### Where Metrics Appear

Each metric shows up in two places in a training task's `status_details`:

- **The latest value**, as a top-level field under its full name (`train_loss`,
`train_lr`, ...). Present only when the metric was actually reported, so a
missing field means no value rather than a zero.
- **The full history**, under `metrics`, as a list of `{step, epoch, value}`
points per metric. This is what the loss curves in the UI are drawn from.

Non-numeric values a framework emits alongside the scalars — histograms, tables,
nested dictionaries — are not charted and do not appear in either place.

## Viewing Your Metrics

Expand Down Expand Up @@ -64,11 +92,20 @@ for step in status.steps or []:
print(f"Epoch: {details.get('epoch')}/{details.get('num_epochs')}")
print(f"Training Loss: {details.get('train_loss')}")
print(f"Validation Loss: {details.get('val_loss')}")
print(f"Learning Rate: {details.get('lr')}")
print(f"Gradient Norm: {details.get('grad_norm')}")
print(f"Learning Rate: {details.get('train_lr')}")
print(f"Gradient Norm: {details.get('train_grad_norm')}")
```

The response includes training progress and metrics including loss, learning rate, and validation loss.
To read the curves rather than the latest values, use the `metrics` payload. It
carries every metric the job reported, so iterating it picks up backend-specific
ones without naming them in advance:

```python
for name, points in (details.get("metrics") or {}).items():
if not points:
continue
print(f"{name}: {len(points)} points, latest {points[-1]['value']}")
```

### Using MLflow

Expand Down
Loading
Loading