Skip to content

fix(instruments): minute-scale buckets for Gym and HTTP duration histograms - #79

Draft
iguehring-nvidia wants to merge 1 commit into
mainfrom
iguehring/gym-duration-buckets
Draft

iguehring-nvidia wants to merge 1 commit into
mainfrom
iguehring/gym-duration-buckets

Conversation

@iguehring-nvidia

@iguehring-nvidia iguehring-nvidia commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

What

gym.rollout.duration_ms, gym.verify.duration_ms and gym.server.request_duration_ms are created without bucket boundaries, so the SDK default applies and its last edge is 10 s. A Gym rollout runs for minutes to tens of minutes, so every sample lands in the overflow bucket and histogram_quantile reports 10 s for any quantile. The FastAPI histograms (http.server.duration in ms, http.server.request.duration in s) have the same problem, because a /run request lasts as long as its rollout.

  • instruments/gym.py: the three duration histograms advise explicit boundaries from 100 ms to 60 min via explicit_bucket_boundaries_advisory; an opentelemetry-api without that parameter falls back to the default.
  • providers.py: the MeterProvider carries two views with the same boundaries (ms and s) for the HTTP histograms.

Evidence

A Gym eval run (Terminal-Bench 4, 8 rollouts lasting 300 to 530 s) exported gym.rollout.duration_ms with all 8 samples in +Inf and bounds [0, 5, …, 10000]; its p95 read 10 s on the dashboard while the span durations put it at 517 s.

Tests

test_duration_histograms_resolve_minutes_not_just_seconds (a 20-minute rollout lands in the 20-minute bucket, nothing in overflow) and TestHttpDurationViews (both HTTP histograms get the boundaries, in their own units). Full suite: 464 passed.

@iguehring-nvidia iguehring-nvidia self-assigned this Oct 5, 2026
@iguehring-nvidia
iguehring-nvidia marked this pull request as draft October 5, 2026 18:36
@copy-pr-bot

copy-pr-bot Bot commented Oct 5, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

…ograms

gym.rollout.duration_ms, gym.verify.duration_ms and gym.server.request_duration_ms
were created without bucket boundaries, so the SDK default applied, whose last
edge is 10 s. A Gym rollout runs for minutes to tens of minutes, so every sample
landed in the overflow bucket and histogram_quantile reported 10 s for any
quantile. The same holds for the FastAPI histograms (http.server.duration in ms,
http.server.request.duration in s), because a /run request lasts as long as its
rollout.

The Gym histograms now advise explicit boundaries from 100 ms to 60 min (older
opentelemetry-api without the advisory parameter falls back to the default), and
the MeterProvider carries views with the same boundaries for the two HTTP
histograms.

Observed on a Gym eval run (Terminal-Bench 4, 8 rollouts of 300 to 530 s): all
8 samples in +Inf, p95 read 10 s; from spans the true p95 was 517 s.

Signed-off-by: Ingo Guehring <iguehring@nvidia.com>
@iguehring-nvidia
iguehring-nvidia force-pushed the iguehring/gym-duration-buckets branch from 8906064 to a2fd7c6 Compare October 8, 2026 01:49
@sshiddib

Copy link
Copy Markdown

Thanks for this, @iguehring-nvidia. Field data that supports merging it:

  • With the default buckets, rollout p50 and p95 both read "10 s"; our logs give 482 s and 894 s. Means from sum and count were correct (509 s vs 517 s).
  • Our slowest rollout took 55 minutes, close to the 60-minute top bucket. For long-reasoning evals, a 2-hour top bucket, or a count of observations above the top bucket, would help.
  • Gym's lock has opentelemetry-api 1.44.0, so the advisory boundaries will apply there. A pip install of the Gym wheel resolves nemo-lens 0.1.0, so pip users would need a Lens release.
  • Model calls: 13% of ours took longer than 10 s (p95 14.1 s). Gym does not record a model-call duration histogram today; if one is added, the same buckets would fit.

Happy to test it on a Slurm cluster with Apptainer.

This branch was successfully deployed

1 active (outdated) deployment
public — 89060643 Deployed Oct 5, 2026 by copy-pr-bot[bot] via release / finalize / notify #159
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants