The ~0.9GB per-apply cond KV cache had two OOM paths on tight cards:
- swapping the reference image left the previous MODEL output (and its
cache) alive in ComfyUI's execution cache while the new one built —
_build_cond_kv now evicts every other state's cache first (they rebuild
lazily if that model is sampled again);
- the cache is allocated lazily inside the first DiT forward, where
comfy's memory manager can no longer make room — a PREPARE_SAMPLING
wrapper now enforces a free-VRAM floor (cache*1.25 + 768MB) before
sampling, partially unloading model weights instead of OOMing.
Verified: headless A->B->A swap run logs 'evicted 1 stale cond KV
cache(s)' per swap, no OOM, outputs clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- adaln_lora_{self_attn,cross_attn,mlp} deltas merge onto
adaln_modulation_*.2.weight as ModelPatcher LoRA patches (strength =
node strength, matching training's delta_scale=multiplier); the
cond-stream prefill subtracts them so the reference stream keeps the
frozen modulation exactly as training did.
- channel-scaled checkpoints: *.inv_scale now pre-scales the cond-LoRA
input (trained function is up(down(x*inv)) — was silently skipped).
- the loader now refuses checkpoints carrying tensors it doesn't map,
instead of silently dropping them (un-applied adaln = garbage output
with no error).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>