feat(pipeline): retry separation on CPU when a GPU attempt fails - #299
Merged
Conversation
One MPS/CUDA failure (OOM, unsupported op, driver hiccup) killed the whole job with "Audio processing failed" -- the Mac Mini report verbatim, where the user needed a LaunchAgent env-var hack to force CPU. The job now retries once on CPU and completes, slower but alive. The fallback is loud, never silent (the #247 lesson applied to the runtime path): the stage line reads "GPU failed -- retrying on CPU (slower)..." while it runs, the WARNING log carries the classified cause and full stderr tail, and gpu_fallback/compute_device persist to job state and metadata. It fires even when the user forced cuda/mps in Settings -- a dead job with no diagnostics is strictly worse than a slow one that explains itself. Mechanics: separate() is now the retry-policy layer over _run_demucs() (one attempt: spawn, stream progress, stall watchdog, cancel translation) with a _demucs_cmd() seam for tests. Partial output from the failed GPU attempt is cleared before the CPU run so collect() can never pick up half-written stems; progress resets to 0 since CPU restarts from scratch. A cancel during the GPU attempt raises JobCancelled without a pointless CPU retry. If CPU also fails, the SeparationError carries both attempts' stderr tails for the quarantine. Closes #276
6 tasks
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.
Closes #276. Phase 2 of #273 — plan: #273 (comment) (PR-2A, the flagship).
What
A single MPS/CUDA failure (OOM, unsupported op, driver hiccup) killed the whole job with the generic "Audio processing failed" — the Mac Mini field report verbatim, where the user resorted to a LaunchAgent env-var hack to force CPU. Jobs now retry once on CPU and complete: slower, but alive and self-explanatory.
Design decisions (from the plan)
errors.classify_failurefrom feat(pipeline): failed-job quarantine + error classification + stage timings #296) + full stderr tail;gpu_fallbackandcompute_device("cpu (fallback from cuda)") persist to job state,metadata.json, and the registry.collect()must never see half-written stems); progress resets to 0 (CPU restarts from scratch); the stall watchdog applies per attempt.JobCancelled, no pointless CPU retry.SeparationErrorcarrying both attempts' stderr tails, so the Error path destroys all evidence #277 quarantine'serror.txtrecords the full story.Mechanics
separate()is now the policy layer over the extracted_run_demucs()(one attempt: spawn, progress streaming, watchdog, cancel translation — moved verbatim), with a module-level_demucs_cmd()seam for tests.Testing
New
tests/test_separate_fallback.py— stubs_demucs_cmdwith Python one-liners so the real process machinery runs end-to-end without demucs/GPU:gpu_fallback=True, warning names device+cause+stderrSeparationErrorwith both tails anddevice="mps, then cpu"JobCancelled, no CPU retryFull suite: 186 passed;
ruff check+ruff format --checkclean.Manual verification path
On the NVIDIA machine: force
demucs_device=cudawith CPU-only torch (the.venv-windev env is exactly this) → job must complete with the fallback stage visible and"gpu_fallback": truein/api/jobs/{id}.🤖 Generated with Claude Code