Skip to content

fix(gpu,render): quiet the foreign-VRAM warning on the display card, pin pooled krea2/LTX-2.5 CLIP+VAE off it - #479

Merged
dmmdea merged 2 commits into
mainfrom
fix/foreign-vram-noise-and-pool-clip
Sep 24, 2026
Merged

dmmdea merged 2 commits into
mainfrom
fix/foreign-vram-noise-and-pool-clip

Conversation

@dmmdea

@dmmdea dmmdea commented Sep 24, 2026

Copy link
Copy Markdown
Owner

Summary

Two operator-reported defects, one PR (clean-ship).

  1. Foreign-GPU-memory warning too noisy (PR fix(gpu): strict FIFO lease queue, fair seat admission, clear-every-resident unload, foreign VRAM warning #469 follow-up). gpu status/gpu reserve's
    "foreign GPU memory holders" warning fired on ordinary desktop apps (Code.exe, PAIR.exe,
    chrome.exe, SnippingTool.exe, msedgewebview2.exe, explorer.exe, csrss.exe, opera.exe) sitting
    on the Qube's DISPLAY card (nvidia-smi index 1) — not a WORK card. Fixed:

    • per-process floor raised 64 -> 512 MiB, now configurable (foreign_gpu_min_mib)
    • OS shell/desktop denylist grows (csrss, explorer, shell-experience hosts)
    • the real fix: a resident whose every KNOWN GPU is a display card is dropped, but only on a
      box that also has a non-display card to score — a single-GPU box (its only card is also its
      display) still warns. Correlation is best-effort: PDH's per-process MiB (no per-card
      identity) cross-referenced against nvidia-smi compute-apps' per-pid gpu_uuid (reported even
      when used_memory is [N/A] on Windows/WDDM) and the existing gpuprobe.DisplayCardUUIDs.
  2. Pooled krea2/LTX-2.5 text encoder loads onto the display card. Measured A/B
    (multigpu-archival-actions-2026-09-24.md): the stock CLIPLoader/VAELoader nodes'
    device input only offers "default"/"cpu" — "default" is ComfyUI's own fastest-first
    pick, independent of imagegen_pool_compute/imagegen_pool_donor, and on the 3x16 reference
    tier that IS the display card. Every pooled krea2 render put the ~12 GiB Qwen3-VL-4B text
    encoder there regardless of which two (non-display) cards the pool keys named. Fixed in
    render/wf-krea2.mjs and render/wf-ltx25-i2v.mjs: when pooled, the text encoder and VAE(s)
    now load through ComfyUI-MultiGPU's CLIPLoaderMultiGPU/VAELoaderMultiGPU, pinned to the
    pool's donor device (verified against the actually-installed plugin source on the Qube,
    C:\ComfyUI\custom_nodes\ComfyUI-MultiGPU\{__init__,wrappers}.py) — never the unnamed
    default. Unpooled builds are unchanged. render/comfy-nodes.mjs and
    internal/mediacap/routeneeds.go updated so doctor/MISSING_NODE name the two new classes.

How tested

  • go build ./..., go test ./... — all green (root package, internal/config,
    internal/mediacap, everything else).
  • node --test render/*.test.mjs — 443/443 green, including new pooled-CLIP/VAE-device
    assertions in wf-krea2.test.mjs/wf-ltx25-i2v.test.mjs.
  • New Go tests: Qube-shaped (3 cards, desktop apps on the display card -> no warning; Resolve on
    a work card -> warning) and OptiPlex-shaped (1 card = display -> Resolve still warns) cases in
    gpu_foreign_test.go, plus effectiveForeignMinMiB coverage.
  • Every new guard broken once (red) and restored, live in this session: the display-card filter
    in classifyForeign (removing it un-suppressed Code.exe on the Qube-shaped fixture) and the
    pooled-CLIP device pin in wf-krea2.mjs (reverting it re-failed both new JS assertions).
  • config.example.json regenerated (go generate ./cmd/genexample) for the new
    foreign_gpu_min_mib key — caught by TestConfigExampleCarriesEveryKey, itself caught by the
    pr-review-toolkit:code-reviewer pass on this branch (its only finding; fixed).
  • One pr-review-toolkit:code-reviewer (Sonnet) review of the whole branch: verified concurrency/
    timeout budget in gpu_foreign.go, the pid/GPU-UUID correlation edge cases, config wiring
    across all three gpu_cmd.go call sites, and consistency between the Go and JS node-pack
    tables. No other findings.

Risk

Low. gpu status/gpu reserve's warning is advisory-only (never gates a lease). The render
change is behind poolVvramGb > 0 (an explicit opt-in) and leaves unpooled builds byte-identical
— confirmed by tests. Neither path is exercised by CI hardware, so behavior is proven by unit
tests against the fixtures/measured values above, not a live render in CI.

🤖 Generated with Claude Code

dmmdea and others added 2 commits September 24, 2026 11:00
…pin pooled krea2/LTX-2.5 CLIP+VAE off it

Two defects reported by the operator against PR #469 and the 2026-09-24 MultiGPU
archival A/B (multigpu-archival-actions-2026-09-24.md):

1. gpu_foreign.go: the foreign-GPU-memory warning fired on ordinary desktop apps
   (Code.exe, chrome.exe, SnippingTool.exe, explorer.exe, ...) sitting on the
   Qube's DISPLAY card, not a work card. Fixed: raised the per-process floor
   64 -> 512 MiB (configurable via foreign_gpu_min_mib), grew the OS shell/
   desktop denylist (csrss, explorer, shell-experience hosts), and — the real
   multi-card fix — a resident whose every known GPU is a display card
   (gpuprobe.DisplayCardUUIDs, cross-referenced against nvidia-smi compute-apps'
   gpu_uuid per pid) is dropped, but only on a box that has a non-display card
   to actually score. A single-GPU box (its only card is also its display)
   still warns on a Resolve-class hog.

2. render/wf-krea2.mjs, render/wf-ltx25-i2v.mjs: the stock CLIPLoader/VAELoader
   nodes' "device" input only offers "default"/"cpu" — "default" is ComfyUI's
   own fastest-first pick, independent of the pool keys, and on the 3x16
   reference tier that IS the display card. Every pooled krea2 render put the
   ~12 GiB Qwen3-VL-4B text encoder there regardless of imagegen_pool_compute/
   _donor. Fixed: when pooled, the text encoder and VAE(s) now load through
   ComfyUI-MultiGPU's CLIPLoaderMultiGPU/VAELoaderMultiGPU pinned to the pool's
   donor device. Unpooled builds are unchanged. render/comfy-nodes.mjs and
   internal/mediacap/routeneeds.go updated so `doctor`/MISSING_NODE name the
   two new classes.

Tests: gpu_foreign_test.go gets Qube-shaped (3 cards, desktop on the display
card -> no warning; Resolve on a work card -> warning) and OptiPlex-shaped
(1 card = display -> still warns) cases, plus effectiveForeignMinMiB coverage.
wf-krea2.test.mjs / wf-ltx25-i2v.test.mjs get pooled-CLIP/VAE-device assertions
and a generic "no loader left on ComfyUI's default device in a pooled graph"
gate. routeneeds_test.go covers the new node-class lists. Every new guard was
broken once (red) and restored, live in this session.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…_min_mib key

go generate ./... (cmd/genexample) after adding config.Config.ForeignGPUMinMiB —
TestConfigExampleCarriesEveryKey caught the missing key, flagged independently
by the pr-review-toolkit:code-reviewer pass on this branch.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@dmmdea
dmmdea merged commit d520701 into main Sep 24, 2026
5 checks passed
@dmmdea
dmmdea deleted the fix/foreign-vram-noise-and-pool-clip branch September 24, 2026 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant