Repository navigation
fix: fail pending prefills when the ProcessPrefillWorker child dies (#168) - #185
Merged
Merged
Conversation
…168) The receiver thread blocked on the reply queue and never checked the child, so an OOM-killed or crashed prefill process left every outstanding future pending forever. The receiver now polls with a timeout; once the child is gone it fails the outstanding futures, and later submits raise, as SubprocessPrefillWorker already does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
ProcessPrefillWorker's receiver thread blocked on_rep.get()and never checked the child. If the prefill process was OOM-killed or segfaulted, its futures never resolved, lanes stayed inprefilling, and later submits hung too.SubprocessPrefillWorker._receivealready fails outstanding futures when its child exits.Changes
opt_prime/opt_prime/accel/pd/pd_batching.py(ProcessPrefillWorker):_receivepolls the reply queue with a 0.5 s timeout. When the queue is empty and the child is no longer alive, it fails every outstanding future withRuntimeError("prefill process exited (<exitcode>)"), sets_futures = Noneand returns. Replies already queued are drained first.submitraisesRuntimeError("prefill process exited")once_futuresisNone, like a submit to a deadSubprocessPrefillWorker(BrokenPipeError).opt_prime/tests/test_pd_batching_disagg.py::test_process_worker_child_death_fails_outstanding_prefills: the factory isfunctools.partial(time.sleep, 600), so the child never serves. The test submits a request, kills the child, and checks thatf.exception(timeout=5)is a RuntimeError and that a later submit raises. The timeout keeps the suite from hanging on the unfixed code.Verification
Python 3.10, torch 2.10.0+cu128, transformers 5.1.0, CPU plus one A100 (
CUDA_VISIBLE_DEVICES=1) on the RNGD+A100 host. Base: optimus-rm @253be20.concurrent.futures.TimeoutErrorafter 5 s (future still pending).tests/test_pd_batching_disagg.pygave 12 passed in 18 s. Futures fail within about 0.5 s of the child's death.opt_prime/:TORCH_DEVICE_BACKEND_AUTOLOAD=0 CUDA_VISIBLE_DEVICES=1 PYTHONPATH=$PWD python3 -m pytest -q tests): 400 passed, 23 skipped before; 401 passed, 23 skipped after.Compatibility and limits
close()nothing changes. The receiver still exits on theNonesentinel.Related Issue
Closes #168
🤖 Generated with Claude Code