Steps, scales & labels
A series is identified by (metric_name, scale, labels). Two points with the same name but a different
scale or different labels go to different series, each with its own step axis. This page covers the
arguments that shape series identity and the step axis.
The step axis
Section titled “The step axis”Each series has its own step axis. The step argument to log controls it:
step value |
meaning |
|---|---|
None (default) |
auto-increment from the series’ last step |
a single int |
the step of the first point; further points in the call continue from it |
| a sequence/array | an explicit step per point (length must match value) |
metrana.log("loss", 0.5) # auto: next stepmetrana.log("loss", [a, b, c], step=100) # steps 100, 101, 102metrana.log("loss", [a, b, c], step=[10, 20, 30]) # explicit stepsAuto-increment is the common case for a single-writer series. Use explicit steps when you log out of order, resume a run, or want a metric pinned to your global training step (see Retrieving the last step).
Timestamps
Section titled “Timestamps”timestamp works exactly like step, in Unix milliseconds:
None(default) — the server stamps each point on arrival.- a single
int— applied to every point in the call. - a sequence/array — one timestamp per point (length must match
value).
import timenow_ms = int(time.time() * 1000)metrana.log("loss", loss, timestamp=now_ms)Scale, labels, and evaluation
Section titled “Scale, labels, and evaluation”These three arguments shape series identity:
The step scale — a StandardMetricScale value: "ML_STEP", "EPISODE", or "ENVIRONMENT_STEP". None
defaults to ML_STEP. Only log / log_distributed take scale; the RL helpers fix their own scale (see
RL metrics).
import metranametrana.log("custom_metric", v, scale=metrana.StandardMetricScale.ML_STEP)metrana.log("custom_metric", v, scale="ML_STEP") # strings work toolabels
Section titled “labels”A dict[str, str] that, together with the name and scale, identifies the series. Two points with the same
name but different labels form different series — useful for splitting a metric by a dimension:
metrana.log("loss", per_layer_loss, labels={"layer": "3"})metrana.log("reward", r, labels={"policy": "greedy"})evaluation
Section titled “evaluation”A shorthand that adds the label {"evaluation": "true"} (unless you already set the evaluation key in
labels), so evaluation points form a series distinct from otherwise identical training points:
metrana.log("reward", train_reward) # training seriesmetrana.log("reward", eval_reward, evaluation=True) # distinct eval seriesmetrana.log("reward", r, labels={"policy": "greedy"}) # distinct labelled seriesRetrieving the last step
Section titled “Retrieving the last step”metrana.get_last_step(metric_name, scale=None, labels=None) returns the last step logged for a series, or
None if nothing has been logged yet. Pass the same scale / labels you logged it with.
This value is seeded from the server at init(), so after a restart or resume you can continue from where
the run left off:
last = metrana.get_last_step("loss")next_step = 0 if last is None else last + 1metrana.log("loss", loss, step=next_step)This is the building block for resuming a run with explicit steps — see
Resuming & forking. The RL equivalent is
get_env_last_rl_step_and_episode.