Skip to content

fix: keep a PD stage accepting work after a refused stop (#174) - #183

Merged
gspark-etri merged 2 commits into
optimus-rmfrom
fix/174-stage-stop-reset
Oct 23, 2026
Merged

gspark-etri merged 2 commits into
optimus-rmfrom
fix/174-stage-stop-reset

Conversation

@gspark-etri

Copy link
Copy Markdown
Collaborator

Background

OwnerExecutor.submit("stop") clears accepting before the owner thread checks quiescence. The owner refuses a stop (409 "owner not quiescent") when the stage is not idle/ready, e.g. poisoned, and after that /v1/admin/reset and a second stop were rejected with 503 "owner not accepting work" while the owner thread kept running. The stage could then neither recover nor shut down (#174: stop -> 409, reset -> 503, stop -> 503, thread still alive).

Changes

  • opt_prime/opt_prime/accel/serve/llmd.py (OwnerExecutor.run, where the result is delivered): when a stop fails, the owner sets accepting = True again before failing the future, so reset and a retried stop are admitted. A successful stop is unchanged.
  • opt_prime/tests/test_pd_recovery.py: test_refused_stop_still_allows_reset_and_stop poisons a stage (fatal transfer error), checks stop -> 409, /v1/admin/reset over HTTP -> 200 {"state": "idle"}, then a second stop succeeds and the owner thread exits.

Verification

CPU plus one A100 (CUDA_VISIBLE_DEVICES=1), Python 3.10, torch 2.10.0+cu128, transformers 5.1.0, base optimus-rm @253be20. The tests bind HTTP on port 0 only.

  • New test on the unfixed code: TORCH_DEVICE_BACKEND_AUTOLOAD=0 CUDA_VISIBLE_DEVICES=1 PYTHONPATH=$PWD python3 -m pytest -q tests/test_pd_recovery.py -k refused_stop -> 1 failed: reset returned 503 (At index 0 diff: 503 != 200).
  • With the fix, serve tests: pytest -q tests/test_pd_recovery.py tests/test_pd_llmd.py tests/test_pd_http_cancel.py tests/test_pd_metrics.py tests/test_pd_stream.py -> 25 passed.
  • Full suite, from opt_prime/: TORCH_DEVICE_BACKEND_AUTOLOAD=0 CUDA_VISIBLE_DEVICES=1 PYTHONPATH=$PWD python3 -m pytest -q tests: before (@253be20, without the new test): 400 passed, 23 skipped, 135 subtests passed; after: 401 passed, 23 skipped, 135 subtests passed.
  • The audit repro (stub service in state "poisoned"): stop -> 409 owner not quiescent, reset -> {'state': 'idle'}, stop -> None, owner thread exits (was 409 / 503 / 503, thread alive).

Compatibility and limits

  • Requests submitted while a stop is queued are still refused with 503, as before. Only a stop that fails reopens the queue.
  • The test helper _close in test_pd_recovery.py still forces started/accepting itself; it is left as it is.

Related Issue

Closes #174

🤖 Generated with Claude Code

gspark-etri and others added 2 commits October 23, 2026 09:56
submit("stop") clears `accepting` before the owner checks quiescence. A
stop is refused (409) only on a non-quiescent stage, e.g. a poisoned one,
and afterwards /v1/admin/reset and a second stop were rejected with 503
"owner not accepting work" while the owner thread kept running. The owner
now restores `accepting` when the stop fails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gspark-etri
gspark-etri merged commit 65e147f into optimus-rm Oct 23, 2026
1 check passed
@gspark-etri
gspark-etri deleted the fix/174-stage-stop-reset branch October 23, 2026 01:07
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.

1 participant