fix: make rollout /run failures recoverable - #1788
Conversation
raise_for_status re-raises aiohttp's ClientResponseError unchanged. It carries request_info/history/headers, which are multidict.CIMultiDictProxy objects that don't pickle. When rollout collection runs under Ray the exception is pickled to cross actors and the run dies with "can't pickle CIMultiDictProxy" - so any resource-server 5xx takes down the whole job instead of failing one rollout. Strip the unpicklable fields; keep status/message/response_content. Signed-off-by: yuchenwang3 <yuchenwang3@users.noreply.github.com>
_post_subroutine doesn't retry /run, so a transient 5xx (e.g. a momentarily overloaded code-exec server) aborts the batch. Retry a few times on 5xx and connection errors; leave 4xx alone. Signed-off-by: yuchenwang3 <yuchenwang3@users.noreply.github.com>
03e29e7 to
22ed1af
Compare
|
Ping — waiting on CI authorization since Jun 26. Could a maintainer |
|
@marta-sd sorry for the direct ping — you've been the main recent committer on |
## Summary - Grant the PR SLA tracker pull-requests: write. - Update the workflow permission regression test. ## Root cause The first tracker run received 403 Resource not accessible by integration while adding an SLA label to PR #1788. The workflow granted only pull-requests: read, so it exited before creating or updating the tracker issue. ## Impact The workflow can now reconcile SLA labels on pull requests and continue to create or update [Tracker] Pull request handoff SLA. ## Validation - .venv/bin/pytest -q tests/unit_tests/test_pr_sla_tracker.py - 24 passed Failed run: https://github.com/NVIDIA-NeMo/Gym/actions/runs/29570272742/job/87852135838 Signed-off-by: Rita Fernandes Neves <rfernandesne@nvidia.com>
|
@kajalj22 pinging you as the most active recent merger in this repo — earlier pings didn't find an owner. This makes rollout |
## Summary - Grant the PR SLA tracker pull-requests: write. - Update the workflow permission regression test. ## Root cause The first tracker run received 403 Resource not accessible by integration while adding an SLA label to PR NVIDIA-NeMo#1788. The workflow granted only pull-requests: read, so it exited before creating or updating the tracker issue. ## Impact The workflow can now reconcile SLA labels on pull requests and continue to create or update [Tracker] Pull request handoff SLA. ## Validation - .venv/bin/pytest -q tests/unit_tests/test_pr_sla_tracker.py - 24 passed Failed run: https://github.com/NVIDIA-NeMo/Gym/actions/runs/29570272742/job/87852135838 Signed-off-by: Rita Fernandes Neves <rfernandesne@nvidia.com>
|
cc @ritaneves for finding a reviewer |
|
Hi @yuchenwang3! For these automatic retries, I think this would just end up with truly failing benchmarks retry longer and fail slower. Typically for these retries we will leave them for the individual servers to handle rather than have a global retry mechnism which may be suboptimal/unintuitive for some scenarios |
|
Fair point on the retry — that half I'm happy to cut. I'd just want to keep the other half from getting thrown out with it, since the bug that actually kills runs has nothing to do with retry policy: On retries themselves, agreed the individual server is the right owner — a global loop can't know which benchmarks are idempotent or how fast a truly-failing one should give up. So how about I drop the retry loop in |
ananthsub
left a comment
There was a problem hiding this comment.
The exception handling change to avoid unpickleable exception content looks good to me. If we can make this PR just that addition without the extra retry loop changes, it's good to merge
| # request_info/history/headers are multidict.CIMultiDictProxy objects | ||
| # that don't pickle, which breaks Ray's cross-actor error propagation | ||
| # (rollout collection dies with "can't pickle CIMultiDictProxy" on any | ||
| # resource-server 5xx). Drop them so the error stays picklable; keep | ||
| # status/message/response_content. | ||
| e.request_info = None | ||
| e.history = () | ||
| e.headers = None | ||
| e.args = (e.status, e.message) |
There was a problem hiding this comment.
@yuchenwang3 this change looks good to me. Let's start with getting this merged without the retry-loop addition
|
Thanks — #2726 takes the exception-serialization fix forward without the retry loop, with stronger spawn-process coverage, and keeps the co-author credit. Closing this one as superseded. |
Replace aiohttp's unpicklable response metadata with plain values while preserving the status, message, URL, headers, and response body. Based on the exception-handling fix proposed by Yuchen Wang in NVIDIA-NeMo#1788. Co-authored-by: Yuchen Wang <yuchenwang3@users.noreply.github.com> Signed-off-by: Ananth Subramaniam <ansubramania@nvidia.com>
Replace aiohttp's unpicklable response metadata with plain values while preserving the status, message, URL, headers, and response body. Based on the exception-handling fix proposed by Yuchen Wang in NVIDIA-NeMo#1788. Co-authored-by: Yuchen Wang <yuchenwang3@users.noreply.github.com> Signed-off-by: Ananth Subramaniam <ansubramania@nvidia.com>
Replace aiohttp's unpicklable response metadata with plain values while preserving the status, message, URL, headers, and response body. Based on the exception-handling fix proposed by Yuchen Wang in NVIDIA-NeMo#1788. Co-authored-by: Yuchen Wang <yuchenwang3@users.noreply.github.com> Signed-off-by: Ananth Subramaniam <ansubramania@nvidia.com>
Replace aiohttp's unpicklable response metadata with pickle-safe values while preserving the status, message, URL, case-insensitive multi-value headers, and response body. Based on the exception-handling fix proposed by Yuchen Wang in NVIDIA-NeMo#1788. Co-authored-by: Yuchen Wang <yuchenwang3@users.noreply.github.com> Signed-off-by: Ananth Subramaniam <ansubramania@nvidia.com>
Replace aiohttp's unpicklable response metadata with pickle-safe values while preserving the status, message, URL, case-insensitive multi-value headers, and response body. Based on the exception-handling fix proposed by Yuchen Wang in NVIDIA-NeMo#1788. Co-authored-by: Yuchen Wang <yuchenwang3@users.noreply.github.com> Signed-off-by: Ananth Subramaniam <ansubramania@nvidia.com>
Replace aiohttp's unpicklable response metadata with pickle-safe values while preserving the status, message, URL, case-insensitive multi-value headers, and response body. Based on the exception-handling fix proposed by Yuchen Wang in NVIDIA-NeMo#1788. Co-authored-by: Yuchen Wang <yuchenwang3@users.noreply.github.com> Signed-off-by: Ananth Subramaniam <ansubramania@nvidia.com>
## Summary - replace unpicklable `aiohttp.ClientResponseError` proxy metadata with pickle-safe values before propagation - preserve HTTP status, message, URL, case-insensitive multi-value request and response headers, and response body - verify the exception and header semantics survive a spawned-process round trip This extracts and hardens the exception-handling fix proposed by @yuchenwang3 in #1788. The original PR also changes rollout retries; this PR intentionally contains only the serialization fix. Co-authored-by: Yuchen Wang <yuchenwang3@users.noreply.github.com> ## Test plan - [x] `uv run --extra dev pre-commit run --files nemo_gym/server_utils.py tests/unit_tests/test_server_utils.py` - [x] `uv run --extra dev pytest tests/unit_tests/test_server_utils.py -q` Signed-off-by: Ananth Subramaniam <ansubramania@nvidia.com> Co-authored-by: Yuchen Wang <yuchenwang3@users.noreply.github.com>
Two issues that together turn one resource-server error into a fatal crash:
raise_for_statusre-raises aiohttp'sClientResponseErrorunchanged. It holdsrequest_info/history/headers, which aremultidict.CIMultiDictProxyobjects that don't pickle. When rollout collection runs under Ray, the exception is pickled to cross actors and the run dies withcan't pickle CIMultiDictProxy— so any resource-server 5xx takes down the whole job instead of failing a single rollout. Strip the unpicklable fields; keepstatus/message/response_content._post_subroutinenever retries/run. A transient 5xx (e.g. a momentarily overloaded code-exec server) aborts the batch. Retry a few times on 5xx/connection errors; leave 4xx alone.How we hit it: under GRPO, a vLLM worker 500s on a NaN logprob (fixed separately in NVIDIA-NeMo/RL#2962). That 500 reaches
raise_for_status, and (1) then crashes the whole rollout collection on the unpicklable exception rather than surfacing the underlying error.