-
Stefy Lanza (nextime / spora ) authored
On the GGUF-isolation split, a torch (video/image) engine and a gguf (text) engine share one NVIDIA card. When one needed VRAM it asked the co-located sibling to release via /internal/evict-vram, but that only evicted the sibling's IDLE models and SKIPPED busy ones — so a text-model load would proceed into the VRAM an in-flight video clip still needed for its forward, and BOTH OOM'd. Recovery then laddered the video load down to disk offload and thrashed for ~1h. Give the cross-engine path the same wait-then-evict the local eviction already has: release_idle_vram(needed_gb, wait_for_busy, wait_timeout) first evicts idle models, then — only if still short — WAITS for each busy model to reach a safe idle point (between requests, e.g. between video clip parts) and evicts it. This converts contention into a CLEAN SWAP: the render's current unit finishes, its model is evicted, the sibling loads alone, and the render reloads + resumes on its next unit. Bounded by wait_timeout (180s) so two mutually-waiting busy engines can't deadlock — one gives up and falls back to its own CPU/disk offload. /internal/evict-vram now reads needed_gb + wait + wait_timeout from the body and forwards them; _cosite_vram_releaser sends wait=True with an HTTP timeout that exceeds the sibling's wait budget so the swap isn't cut short. Symmetric: both engines register the releaser at each other, so either direction swaps cleanly. Co-Authored-By:
Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RdMufYvtTbtGDWsiZVoXce
c9791579