Distributed logging
When several processes (e.g. distributed-training ranks, or parallel rollout workers) log into one run, three things matter: they must agree on the run, they must use the right log function for shared series, and RL series need an exclusive owner per (environment, episode).
1. Agree on the run (orchestration_id)
Section titled “1. Agree on the run (orchestration_id)”Every process that should share a run needs the same orchestration_id. If you don’t pass one, it is
resolved automatically, in order, from:
METRANA_ORCHESTRATION_ID- the framework job ids
TORCHELASTIC_RUN_ID/SLURM_JOB_ID/RAY_JOB_ID - a random token (which only descendants that inherit the environment will match)
The resolved value is published back to METRANA_ORCHESTRATION_ID, so forked/spawned children inherit it.
With resume_strategy="never" (the default), the first process creates the run and the rest resume it
by matching this identifier; a genuinely different job hitting the same run name errors instead of
corrupting it (see Resuming a run).
# torchrun / Slurm / Ray: nothing to do — the framework job id is picked up automatically.metrana.init(api_key="...", workspace_name="ws", project_name="proj", run_name="run")
# Custom launcher: pass a token shared by all workers of the job.metrana.init(..., orchestration_id="job-2025-06-23-abc")2. Choose the right log function for shared series
Section titled “2. Choose the right log function for shared series”Use metrana.log_distributed(...) (instead of metrana.log(...)) when multiple processes write to the
same series — for example all ranks logging a global loss. It uses unordered, merge semantics so
concurrent writers don’t conflict. Provide an explicit step (the global training step) so points from
different ranks align on the same axis:
metrana.log_distributed("loss", loss, step=global_step)Use plain metrana.log(...) for series owned by a single writer — it is ordered and can auto-increment.
Pin logger_id (e.g. one per rank) if you want the backend to distinguish a restarted writer from a
genuinely new concurrent one.
| Series ownership | Function | Semantics |
|---|---|---|
| One writer | log |
Ordered; can auto-increment the step. |
| Many writers | log_distributed |
Unordered/merge; pass an explicit global step. |
3. RL metrics need an exclusive owner per (environment, episode)
Section titled “3. RL metrics need an exclusive owner per (environment, episode)”The RL functions (log_rl_episode, log_rl_environment_step) are ordered, and the unit of ownership
is the (environment, episode) pair: each episode of each environment must be logged by exactly one
process. Sharding whole environments across ranks (e.g. a vectorized env split over workers) satisfies
this automatically. Sharding episodes of one environment across parallel rollout workers — each worker
running its own episodes of env_id="cartpole" — works too, provided each worker passes a unique episode_id.
log_rl_episode— pass an explicitepisode. This switches the series to unordered (merge) semantics: you own the episode numbering, and parallel workers’ points merge cleanly instead of contending for one auto-increment cursor.log_rl_environment_step— nothing special: log normally withepisode=...set. Env steps are numbered within each episode, so writers that own different episodes never contend.
# each rollout worker logs only the episodes it ran; env0 is shared by many workersmetrana.log_rl_episode("episode_return", ep_return, rl_step=rl_step, env_id="env0", episode=my_episode) # explicit -> merge
metrana.log_rl_environment_step("reward", rewards, rl_step=rl_step, env_id="env0", episode=my_episode)Plain log / log_distributed float series have no per-env restriction (log_distributed is explicitly
built for many writers on one series).
Create-only attributes and the disk spool
Section titled “Create-only attributes and the disk spool”Two related rules for the multi-process case:
- Create-only attributes.
config/tags/description/ git SHA frominit()are applied only by the creating process, so resuming siblings never clobber them. See Config & attributes. - Disk spool isolation. Concurrent writers must never share one spool directory — give each its own
container/volume or a distinct
disk=path. See Disk spool → Multiple processes.