nemo_rl.telemetry.metrics#
Best-effort mirroring of NeMo-RL’s async efficiency metrics into OTel.
Kept out of nemo_rl.utils.logger (which pulls in torch/ray/wandb/etc.) so
the mapping stays importable and testable without the heavy training stack.
nemo_rl.utils.logger.Logger.log_metrics calls :func:tee_rl_metrics_to_otel
after its normal fan-out to the file/wandb/mlflow backends.
The async efficiency/* phase durations are emitted from instruments owned
here, because they are keyed by NeMo-RL’s own efficiency-category labels and
lens has no fixed field for them.
Logger.log_metrics fans a step out as several dicts under different
prefixes, and a key is only reachable from the prefix its own dict carries — so
only the prefixes the efficiency dict actually arrives under are teed.
Module Contents#
Functions#
Coerce a logged value to float, or None when it is not a usable scalar. |
|
Warn with a traceback the first time key fails, then stay quiet. |
|
Map each canonical efficiency category to its measurement kind. |
|
Return the period one efficiency value covers (see the constants above). |
|
Extract |
|
Create (once per Meter) the efficiency gauges. |
|
Emit the |
|
Mirror the async efficiency durations into OTel (no-op unless exporting). |
|
Body of :func: |
Data#
API#
- nemo_rl.telemetry.metrics.logger#
‘getLogger(…)’
- nemo_rl.telemetry.metrics._TRAIN_PREFIXES: tuple[Optional[str], ...]#
(‘train’, ‘’)
- nemo_rl.telemetry.metrics._scalar(value: Any) Optional[float]#
Coerce a logged value to float, or None when it is not a usable scalar.
- nemo_rl.telemetry.metrics.RL_EFFICIENCY_SECONDS_METRIC#
‘rl.efficiency.seconds’
- nemo_rl.telemetry.metrics.RL_EFFICIENCY_PCT_METRIC#
‘rl.efficiency.pct’
- nemo_rl.telemetry.metrics.RL_EFFICIENCY_MEASUREMENT_ATTR#
‘rl.efficiency.measurement’
- nemo_rl.telemetry.metrics.WALL_CLOCK_MEASUREMENT#
‘wall_clock’
- nemo_rl.telemetry.metrics.COLLECTOR_WALL_CLOCK_MEASUREMENT#
‘collector_wall_clock’
- nemo_rl.telemetry.metrics.THREAD_SECONDS_MEASUREMENT#
‘thread_seconds’
- nemo_rl.telemetry.metrics.RL_EFFICIENCY_WINDOW_ATTR#
‘rl.efficiency.window’
- nemo_rl.telemetry.metrics.STEP_WINDOW#
‘step’
- nemo_rl.telemetry.metrics.RUN_WINDOW#
‘run’
- nemo_rl.telemetry.metrics._RUN_WINDOW_WALL_CLOCK_CATEGORIES: frozenset[str]#
‘frozenset(…)’
- nemo_rl.telemetry.metrics._EFFICIENCY_KEY_PREFIX#
‘efficiency/’
- nemo_rl.telemetry.metrics._EFFICIENCY_SECONDS_SUFFIX#
‘_s’
- nemo_rl.telemetry.metrics._EFFICIENCY_PCT_KEY#
‘efficiency/efficiency_pct’
- nemo_rl.telemetry.metrics._EFFICIENCY_PCT_PER_STEP_KEY#
‘efficiency/efficiency_pct_is_per_step’
- nemo_rl.telemetry.metrics._EFFICIENCY_INSTRUMENTS: weakref.WeakKeyDictionary#
‘WeakKeyDictionary(…)’
- nemo_rl.telemetry.metrics._WARNED: set[str]#
‘set(…)’
- nemo_rl.telemetry.metrics.warn_once(key: str, message: str) None#
Warn with a traceback the first time key fails, then stay quiet.
Telemetry failures are typically per-step and deterministic – a broken instrument fails identically on every step – so warning each time would put thousands of identical tracebacks in a run’s log while telling the reader nothing the first one did not. Warning level once, so a permanently dead sink is visible at default verbosity; debug afterwards, so the repetition is still recoverable when someone is looking for it.
- nemo_rl.telemetry.metrics.efficiency_measurements() dict[str, str]#
Map each canonical efficiency category to its measurement kind.
- Returns:
{category: "wall_clock" | "collector_wall_clock" | "thread_seconds"}, or an empty dict when the training stack is unavailable — which makes the efficiency tee a no-op instead of an import error.
- nemo_rl.telemetry.metrics.efficiency_window(category: str, measurement: str) str#
Return the period one efficiency value covers (see the constants above).
- nemo_rl.telemetry.metrics.map_efficiency_seconds(
- metrics: dict[str, Any],
- measurement_by_category: Mapping[str, str],
Extract
{category: seconds}from a raw Logger metrics dict.Looks up only the categories in measurement_by_category, which keeps the aggregate
efficiency/*keys (total_waste_s,productive_time_s,total_wall_time_s,thread_seconds_total_s) out of the per-category series even though they share the prefix and suffix.Pure function (no OTel side effects) so it is trivially unit-testable.
- nemo_rl.telemetry.metrics._get_efficiency_instruments(
- meter: opentelemetry.metrics.Meter,
Create (once per Meter) the efficiency gauges.
- nemo_rl.telemetry.metrics._tee_efficiency_metrics(
- meter: opentelemetry.metrics.Meter,
- metrics: dict[str, Any],
Emit the
efficiency/*phase durations asrl.efficiency.*.
- nemo_rl.telemetry.metrics.tee_rl_metrics_to_otel(
- metrics: dict[str, Any],
- prefix: Optional[str],
Mirror the async efficiency durations into OTel (no-op unless exporting).
Only the
efficiency/*durations logged alongside the driver’s per-steptrainscalars are teed. The OTel instruments are touched only when telemetry is actively exporting; everything else short-circuits to a no-op.Never raises.
Logger.log_metricscalls this unguarded on every step, so the guarantee has to live here: the emit path below has its own handler, and this one covers everything around it – reading the handle, dispatching on the prefix – so no shape of telemetry failure can reach a training step.
- nemo_rl.telemetry.metrics._tee_rl_metrics_to_otel(
- metrics: dict[str, Any],
- prefix: Optional[str],
Body of :func:
tee_rl_metrics_to_otel, inside its exception guard.