Rank Straggler Policy¶
This page documents how TraceML decides that one rank in a distributed job is a straggler, which rank it blames, and how confident it is. It is the developer reference behind the Step Time rank-straggler diagnoses. For the user-facing walkthrough of a slow rank, see Diagnosing a slow rank in DDP. For the shared timing definitions, see the Step Time glossary.
The implementation lives in src/traceml_ai/diagnostics/ (rule evaluation and
culprit/victim context) and src/traceml_ai/reporting/primary_diagnosis.py
(evidence assembly). The canonical policy summary is
src/traceml_ai/diagnostics/DIAGNOSIS.md (Step Time section); this page expands
on it.
Diagnosis kinds¶
Rank-straggler diagnoses describe skew across ranks in a single analyzed
window, as opposed to the single-rank bottleneck kinds (INPUT_BOUND,
COMPUTE_BOUND, RESIDUAL_HEAVY).
| Kind | Meaning |
|---|---|
STRAGGLER |
Visible rank skew exists, but no measured component explains enough of the visible wait to name a cause. |
INPUT_STRAGGLER |
The culprit rank has materially higher selected-clock input wait than the victim. |
COMPUTE_STRAGGLER |
DDP / default strategy only: the culprit rank has materially higher forward time than the victim. |
H2D_STRAGGLER |
The culprit rank has materially higher host-to-device transfer time than the victim. |
Selected clock and eligibility¶
Step Time diagnosis analyzes one selected clock for the window. It uses GPU
event timing when every rank and step has GPU timing for Traced Step Time,
Input Wait, and traced phase events; otherwise it falls back to explicit
cpu_ms timing. All rank-straggler comparisons below are in that selected
clock.
TraceML first picks one visible synchronization phase per rank:
visible_r = backward_r # DDP / default
visible_r = forward_r + backward_r # FSDP
Only ranks with a measured visible-phase anchor, measured Traced Step Time, and measured Input Wait are eligible:
DDP / default: input_wait measured and backward_r > 0 and step_time_r > 0
FSDP: input_wait measured and forward_r > 0 and backward_r > 0
and step_time_r > 0
If fewer than two ranks are eligible, TraceML does not report a rank straggler.
Missing instrumentation makes the rule abstain rather than treat a zero as a
fast rank; when that abstention leaves the whole window without any finding,
Step Time reports INCOMPLETE_DATA with the missing signal names instead of
BALANCED. Component values of input_wait == 0 and h2d == 0 are still
valid measurements and are kept: a metric measured somewhere in the window is
never confused with one that was never measured at all.
Culprit and victim selection¶
- The culprit is the rank with the minimum visible value. It is the rank that most likely arrived late at the synchronization phase and therefore waited least in it.
- The victim is the upper actual median rank by visible value. Using the upper median rather than the maximum keeps the reference rank representative of the group instead of a single outlier.
Straggler score¶
The score normalizes the visible gap between victim and culprit by the victim's own selected-clock iteration cost:
denom = input_wait_victim + step_time_victim
score = (visible_victim - visible_culprit) / denom
If score < 0.10, TraceML does not report a rank straggler. At 10% it emits a
warning; at 20% it emits critical severity when the existing confidence gates
permit it. The gap below 10% is treated as normal run-to-run variation rather
than a real straggler.
Attribution¶
Once the score clears the threshold, TraceML compares the culprit directly with the victim to explain the visible wait:
input_excess = input_wait_culprit - input_wait_victim
h2d_excess = h2d_culprit - h2d_victim # only when H2D is
# measured on both ranks
forward_excess = forward_culprit - forward_victim # DDP / default only
Each excess is converted into bounded cause coverage of the visible wait:
cause_coverage = min(1, component_excess / visible_cost)
The component with the highest coverage names INPUT_STRAGGLER,
H2D_STRAGGLER, or (DDP / default only) COMPUTE_STRAGGLER only when its
coverage reaches 80%. Every candidate component must be measured on both the
culprit and the victim rank: DDP / default compute attribution requires
measured forward time on both, and H2D attribution requires measured H2D time
on both, so an unmeasured phase can never name the cause. Otherwise the
diagnosis stays STRAGGLER with a sync-or-unattributed component. The issue
evidence includes both component_excesses_ms and component_coverage, keyed
by input, h2d, and compute; components excluded for missing measurement
are absent from both maps.
Cause coverage chooses the diagnosis label. The straggler score above remains the sole source of warning or critical severity. Generic residual attribution can cover validation, checkpointing, logging, framework orchestration, CPU stalls, or unobserved transfer stalls inside the timed step. It is not direct NCCL, all-reduce, or synchronization timing.
Training strategy context¶
When runtime environment metadata is available, Step Time diagnosis receives an
advisory training strategy such as ddp or fsdp. This context only chooses
attribution behavior; it is not a public Step Time metric. Missing or
unrecognized strategy metadata defaults to ddp to preserve the DDP / default
visible-backward straggler behavior.
- DDP / default stays eligible for critical rank-straggler diagnoses once thresholds and confidence gates are met.
- FSDP diagnoses are capped at warning, because collective masking can make cross-rank attribution under-confident.
Confidence gates¶
Shared Step Time diagnosis needs at least 2 steps to emit warning-only diagnoses, and at least 20 steps before a critical diagnosis is allowed. The live CLI table, dashboard, and final summary use the same gates and the same global-rank window loader; they differ only by the selected timing window size.
See also¶
- Diagnosing a slow rank in DDP
- Reading Output
src/traceml_ai/diagnostics/DIAGNOSIS.md(canonical Step Time policy)