1. 24 Jul, 2026 5 commits
  2. 23 Jul, 2026 9 commits
  3. 22 Jul, 2026 20 commits
  4. 21 Jul, 2026 2 commits
    • Stefy Lanza (nextime / spora )'s avatar
      frontproxy: accept port-specific session_<port> cookie in telemetry auth · 8a9e0183
      Stefy Lanza (nextime / spora ) authored
      The session cookie is named session_<port> so two instances on one host don't
      clobber each other's cookie, but the lightweight front telemetry auth only
      checked the literal "session" name — 401'ing every front-served status call.
      Match the engine's get_current_user and accept any session / session_* cookie.
      Co-Authored-By: 's avatarClaude Opus 4.8 <noreply@anthropic.com>
      Claude-Session: https://claude.ai/code/session_01EPLnsRpNBzWCHLgkXATqRz
      8a9e0183
    • Stefy Lanza (nextime / spora )'s avatar
      embeddings: multimodal (text+image) support + correct VRAM tracking/eviction · dd848607
      Stefy Lanza (nextime / spora ) authored
      Wire up real image embeddings and make embedding models first-class in the
      VRAM lifecycle.
      
      - api/embeddings.py: detect CLIP/SigLIP dual encoders and drive them through
        transformers get_text_features/get_image_features so text and images share
        one projected space (ST path kept for repos shipping a native recipe).
        request.image is now actually read (URL/data-URI/path/base64), vectors are
        appended after the text ones, and text-only models return a clear 400.
        Handle the transformers 5.x pooled-output return shape.
      - Wrap the loaded model in _EmbeddingModel (unpacks as (backend, model) but
        exposes cleanup()) and register it via add_model() + record_vram_delta() on
        the request path, so it is measured, LRU-tracked, and cleanly evicted like
        every other model type instead of leaking as a bare tuple.
      - admin: fix the model-load button for embeddings (was routed to the diffusers
        loader) to use _load_embedding_model, matching the request path.
      - admin: backfill used_vram_gb after a download completes, since the entry is
        saved before the weights exist on disk; factor the estimate into a shared
        _estimate_used_vram_gb helper. A freshly-downloaded CLIP/SigLIP entry now
        always carries a reasonable estimate so pre-load eviction sizes correctly.
      Co-Authored-By: 's avatarClaude Opus 4.8 <noreply@anthropic.com>
      Claude-Session: https://claude.ai/code/session_01EPLnsRpNBzWCHLgkXATqRz
      dd848607
  5. 03 Jul, 2026 3 commits
    • Stefy Lanza (nextime / spora )'s avatar
      township: Run page invents characters/environments from scratch, phased · 15a0e81b
      Stefy Lanza (nextime / spora ) authored
      Two changes to the Run-page character/environment generation:
      
      1. Generate FROM SCRATCH via the text model instead of the built-in static pool.
         stage_characters/stage_environments always iterated FIGHTER_POOL/
         ENVIRONMENT_POOL and used their hardcoded (pre-fallback) prompts — the LLM was
         never invoked for a full run. New _invent_profiles() calls the text model
         (_autogen_profile_payload) to invent fresh profiles; the static pool is only a
         fallback when no text model is configured (with a clear warning).
      
      2. Phase the pipeline: invent ALL prompts first, then render ALL reference images,
         then train image LoRAs, then video LoRAs (prompts → images → image-LoRA →
         video-LoRA). New _render_profile_images() does the image phase from the saved
         prompts; the reuse/skip paths are unchanged. num_fighters/num_environments set
         how many to invent (default: the pool size).
      
      (CLI main() still uses the pool-based stage_characters/stage_environments; the
      web Run page is the phased-from-scratch path.)
      Co-Authored-By: 's avatarClaude Opus 4.8 <noreply@anthropic.com>
      Claude-Session: https://claude.ai/code/session_01RdMufYvtTbtGDWsiZVoXce
      15a0e81b
    • Stefy Lanza (nextime / spora )'s avatar
      lora-train: cross-engine GPU lock so nothing reloads mid-training (fix intermittent OOM) · 18c6a358
      Stefy Lanza (nextime / spora ) authored
      evict_cosited_siblings() frees the co-located sibling's VRAM ONCE at training
      start, but training runs for minutes as an in-engine background job that the front
      swap-gate can't cover (its POST returns a job_id immediately). So a concurrent LLM
      request reloaded the gguf text model mid-training and OOM'd the trainer (one
      fighter LoRA failed while others succeeded).
      
      Add codai/models/gpu_lock.py: a cross-engine GPU reservation. Training reserves the
      card for its whole duration — locally AND on co-located siblings via new
      /internal/gpu-reserve + /internal/gpu-release endpoints — and every ordinary
      model-load path (manager.request_model, video _load_video_pipeline, image
      _load_diffusers_pipeline) calls wait_until_free() first. A request that needs a
      load during training now BLOCKS until training releases, then loads and serves —
      the same queue-behind-the-owner behaviour the swap-gate gives request-level work,
      now extended to cover training. The training thread is exempt from its own
      reservation, so loading the base model never self-deadlocks; waits are bounded
      (900s) so a stuck reservation can't hang forever.
      
      Validated: sibling reservation blocks a loader thread until release; the reserving
      thread never waits on itself.
      Co-Authored-By: 's avatarClaude Opus 4.8 <noreply@anthropic.com>
      Claude-Session: https://claude.ai/code/session_01RdMufYvtTbtGDWsiZVoXce
      18c6a358
    • Stefy Lanza (nextime / spora )'s avatar
      images: stop video's flash-attn backend leaking to image models (Z-Image attn_mask crash) · 0043eb2a
      Stefy Lanza (nextime / spora ) authored
      diffusers' Model.set_attention_backend() doesn't just set per-processor backends
      — it ALSO flips a process-wide active backend (attention_dispatch's
      _active_backend). The video path sets that to flash-attn for the Wan transformer;
      image and video share the nvidia-engine process, so the global stayed flash and
      leaked to the next image model. Z-Image's transformer sets no backend of its own
      (passes backend=None → uses the global) and its attention is masked, so it
      crashed with "`attn_mask` is not supported for flash-attn 2" → image/environment
      generation 400. reset_attention_backend() clears per-processor backends but NOT
      the global, so it didn't help.
      
      Fix: restore the diffusers global backend to the env default (native/SDPA)
      (a) before every image generation — bulletproof against a leaked flash backend —
      and (b) in the video pipeline teardown (_free_pipeline_vram), so it can't persist
      after a video pipe is freed. Masked image attention (SDPA) now always works; the
      video transformer keeps its own per-processor backend.
      Co-Authored-By: 's avatarClaude Opus 4.8 <noreply@anthropic.com>
      Claude-Session: https://claude.ai/code/session_01RdMufYvtTbtGDWsiZVoXce
      0043eb2a
  6. 02 Jul, 2026 1 commit
    • Stefy Lanza (nextime / spora )'s avatar
      lora-train: evict co-located sibling engine's VRAM before training (fix OOM) · e300e9c4
      Stefy Lanza (nextime / spora ) authored
      LoRA training freed VRAM with unload_all_models(), which only unloads THIS
      engine's models. On the GGUF-isolation split the co-located gguf (text) engine
      kept its model resident (~7.4 GB), so fp32 training (~16 GB) + the sibling
      exceeded the 24 GB card → "CUDA out of memory. Tried to allocate 32 MiB … 26 MiB
      free … Process 226 has 7.36 GiB" — every fighter LoRA (dlaba, zigo, zlo, …)
      failed. Training also isn't covered by the front swap-gate, so nothing else
      cleared the sibling.
      
      Add multi_model_manager.evict_cosited_siblings(): invoke the registered
      cross-engine VRAM releasers (the cosite releaser posts wait=True, so it waits for
      a busy sibling to reach a safe point). Call it right after unload_all_models() in
      both training paths (image + video/Wan), so training gets the whole card.
      Co-Authored-By: 's avatarClaude Opus 4.8 <noreply@anthropic.com>
      Claude-Session: https://claude.ai/code/session_01RdMufYvtTbtGDWsiZVoXce
      e300e9c4