Skip to content

fix(rollout): wait up to --session-collect-timeout for a session's samples [fork fix-017] - #50

Merged
listar2000 merged 2 commits into
mainfrom
session-collect-timeout-fix017
Oct 19, 2026
Merged

listar2000 merged 2 commits into
mainfrom
session-collect-timeout-fix017

Conversation

@listar2000

@listar2000 listar2000 commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner

Merge with rebase, not squash

Replaces #49 (same change, renumbered to fix-017 after review).

Outcome

Finished agent runs no longer get thrown away when the server holding their data is slow to hand it back. The trainer now waits up to 30 min (new flag --session-collect-timeout) instead of a fixed 2 min.

Words used below:

  • A try is one agent working one task once. Training uses groups of 16 tries on the same task, and scores each try against the others in its group.
  • While a try runs, a session on a session server records every model call it makes. When the agent finishes, the trainer collects that record as training samples, then deletes the session.
Before After
Wait for a finished try's samples 120 s, fixed --session-collect-timeout, default 1,800 s
Wait for the session delete 120 s, fixed the same flag
What a timeout costs the try is dropped, and with it its whole group of 16 unchanged, but only a stuck server should reach it
3-node DeepSeek-V4.1-Flash overfit run 134 finished tries lost, 15 groups dropped, the next step waited 29 min for its batch expected: none lost to this

In that run, the 32 session servers ran on the head trainer node. Every one of the 134 timeouts landed while the trainer was running its optimizer step. The head node's optimizer step also took about 30% longer than the other trainer node's, so CPU contention on that node is the likely cause (inferred, not measured per process). All of those tries had finished normally. After this change, a slow session server costs a few minutes, not a whole group.

Patch page: fork/patches/fix-017-session-collect-timeout.md

Contract

  • New argument --session-collect-timeout (float, seconds, default 1800). It bounds both the request for a finished session's samples and the session delete. Recipes don't need to set it.
  • OpenAIEndpointTracer(..., collect_timeout=120) is a new keyword with the old value as its default, so direct constructions behave as before. OpenAIEndpointTracer.create(args) reads the argument.

Side-effects

  • Upstream files touched, all marked [fork fix-017]: miles/rollout/generate_utils/openai_endpoint_utils.py, miles/utils/arguments.py, tests/fast/rollout/generate_utils/test_openai_endpoint_utils.py.
  • A session server that is truly stuck now holds its try for up to 30 min before the group is dropped, instead of 2 min. Other groups keep filling the batch in the meantime.
  • Not included: moving the session servers off the head trainer node. That would remove the cause, but the session proxy forwards only to the head's address, so it is a separate change that needs a GPU check.
  • Both this PR and fix(rollout): score-centering candidates as flat base64 arrays [fork fix-016] #45 add a row to fork/patches/README.md; they merge cleanly in either order.

Done

  • Rollout: collect_samples uses self.collect_timeout for both calls, and create() takes it from args.session_collect_timeout.
  • Arguments: --session-collect-timeout in the session argument group.
  • Tests: create reads the argument, and both calls get the bound.
  • Patch page fork/patches/fix-017-session-collect-timeout.md and its README row.

Verification

  • python fork/tools/ledger.py check: ok.
  • pre-commit run --from-ref c678bbd778 --to-ref HEAD: all hooks pass.
  • In the launch image built from this branch (CPU container): pytest tests/fast/rollout/generate_utils/test_openai_endpoint_utils.py tests/fast/rollout/test_fully_async_rollout.py tests/fast/rollout/session gave 416 passed and 3 failed. Two failures are test_session_server_benchmark[v1|v2], which also fail on main c678bbd in the same container. The third, test_post_buffer_no_retry_closes_stalled_body_connection[cancel], is a timing race that fails at random on main and on this branch alike (1 of 3 repeat runs failed on main, 0 of 3 here).
  • The two new tests fail on main's code in under 3 s: create() sets no collect_timeout (AttributeError), and the constructor rejects collect_timeout (TypeError).
  • No GPU run yet. The next DeepSeek-V4.1 overfit run will show whether any Failed collecting samples lines remain.

…mples [fork fix-017]

Collecting a finished session's training samples and deleting the session had a
fixed 120 s bound. A timeout aborts the sample and the group filter drops the
whole group. The new --session-collect-timeout (default 1,800 s) bounds both
calls; it only has to catch a stuck server.

Patch page: fork/patches/fix-017-session-collect-timeout.md

Fork-Fix: fix-017
Touches: miles/rollout/generate_utils/openai_endpoint_utils.py, miles/utils/arguments.py, tests/fast/rollout/generate_utils/test_openai_endpoint_utils.py
Evidence: a 3-node DeepSeek-V4.1-Flash overfit run lost 134 tries to "Failed collecting samples: TimeoutError" at 120 s, all during the trainer's optimizer phases; 15 groups dropped, the next step waited 29 min for its batch
Upstream-Status: not filed
Remove-When: upstream makes the collection bound configurable, or session servers stop sharing a node with the trainer's optimizer
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Fork-Infra: patch-fix-017
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@listar2000
listar2000 marked this pull request as ready for review October 19, 2026 18:30
@listar2000
listar2000 merged commit cc2a5a9 into main Oct 19, 2026
@listar2000
listar2000 deleted the session-collect-timeout-fix017 branch October 19, 2026 19:05
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