Retry an engine that dies on the way up during startup replay - #63
Merged
Conversation
…eplay Rolling 0.5.4 onto spark-3 lost its model. The startup sweep killed the running engine and replay relaunched immediately, while the driver was still releasing the GPU from the container that had just died. The nvidia hook handed the new container no device (Can't initialize NVML, No CUDA runtime is found, Triton '0 active driver(s) found', No module named 'vllm._C') and it exited during weight load. Nothing retried, so the node came back advertising nothing and the model stayed missing until a human re-loaded it. Re-issuing the identical load a few minutes later worked with zero GPU-failure lines. Note this is NOT a failed launch check. The container reached Running, so start_solo() correctly returned True; the engine died minutes later during load. The gap was that nothing watched it afterwards. _ensure_serving() now waits for an engine to bind and, if it never does, waits 30s for the GPU to finish releasing and relaunches once. Applied to both the boot primary and each replayed stacked instance. The retry is deliberately single: a model that fails twice has a real problem and a retry loop would hide it. Diagnosable at all only because of 0.5.4 — dropping --rm left the corpse with readable logs. Before that this was silence. Tests: 6 new. 708 pass, ruff clean.
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.
Problem
Rolling 0.5.4 onto spark-3 lost its model. The startup sweep killed the running engine and replay relaunched immediately, while the driver was still releasing the GPU from the container that had just died. The nvidia hook handed the new container no device and it exited during weight load:
Host
nvidia-smiwas healthy throughout, and a container launched from inside the orchestrator saw the GPU fine. Re-issuing the identical load a few minutes later worked with zero GPU-failure lines, which is what identifies it as a release race rather than a broken node.Nothing retried, so the node came back advertising nothing and the model stayed missing until a human re-loaded it. That is the worst shape for this failure: a restart looks successful and the model is just gone.
Worth being precise, because the first diagnosis was wrong: this is NOT a failed launch check. The container reached Running, so
start_solo()correctly returned True. The engine died minutes later, during weight load. The gap was that nothing watched it after the launch confirmation.Fix
_ensure_serving()waits for an engine to bind and, if it never does, waits 30 seconds for the GPU to finish releasing and relaunches once. It is applied to both the boot primary and each replayed stacked instance.The retry is deliberately single. A model that fails twice has a real problem, and a retry loop would hide it behind minutes of silence.
Tests
6 new, covering: no relaunch when the engine binds first time, one relaunch when it never binds, giving up after exactly one retry, a relaunch that fails to start, a relaunch that raises, and that the retry actually waits before asking for the GPU again. 708 pass, ruff clean.
This was only diagnosable because of #62 — dropping
docker run --rmleft the crashed container as a readable corpse. Before that it was silence, which is how it went unnoticed.