• Stefy Lanza (nextime / spora )'s avatar
    frontproxy: intelligent per-shared-GPU model-swap queue (batch, then swap) · c0a970b0
    Stefy Lanza (nextime / spora ) authored
    Builds on the cross-engine clean-swap eviction: instead of two engines on one
    shared card ever running forwards concurrently (→ VRAM contention → OOM →
    disk-thrash), the front now serializes model OWNERSHIP of a shared GPU while
    batching to avoid per-request thrash.
    
    New GpuSwapGate (frontproxy/reqqueue.py), one per shared-GPU group (keyed by the
    co-located engines' CODERAI_ENGINE_GPUS selector, created only when an engine has
    a sibling on its card):
    
      * A request for the model that currently OWNS the GPU runs immediately — a swap
        isn't needed (a lone stream never stalls). Concurrency stays capped downstream
        by the existing per-model FrontQueue.
      * A request for a DIFFERENT model queues. The owner keeps being served up to
        `cap` requests (server.gpu_swap_batch, default 10) while another model waits,
        then — once the owner is fully idle (never mid-request) — the GPU SWAPS to the
        waiting model (which evicts + loads), serves it, and round-robins BACK if the
        original has requests queued. No thrash (batch), no starvation (cap).
    
    Wired into all four dispatch paths (broker, broker-stream, direct stream with
    keepalive, direct non-stream) for every GPU-inference kind (text/image/video):
    acquire the swap slot before the per-model queue, release in the finalizer;
    cancelling a pending acquire (client disconnect) drops the waiter with no leak.
    The text-stream path emits keepalives while waiting out a swap so the client
    doesn't time out.
    
    Scheduler validated by async unit tests: cap engages at exactly N with a
    competitor waiting; a lone same-model stream runs unbounded; round-robin
    alternates; cancelled waiters leak no slot.
    Co-Authored-By: 's avatarClaude Opus 4.8 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01RdMufYvtTbtGDWsiZVoXce
    c0a970b0
config.py 44.9 KB