Skip to content

CUDA memory pools to avoid vram fragmentation#1620

Open
dxqb wants to merge 3 commits into
Nerogar:masterfrom
dxqb:mempool
Open

CUDA memory pools to avoid vram fragmentation#1620
dxqb wants to merge 3 commits into
Nerogar:masterfrom
dxqb:mempool

Conversation

@dxqb

@dxqb dxqb commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

employ CUDA mempools to avoid vram fragmentation
this CR is ~ 100 lines, but it's based on #1617 so it'll initially show a large diff

Test plan

  • pre-commit run --all-files passes
  • Launched the affected UI or script and exercised the change
  • Tested with at least one real preset / config when relevant (note which: ____)

AI assistance

  • AI-assisted — I have read every line in this diff and can defend each change

dxqb and others added 2 commits July 15, 2026 00:07
…()/evict() API

Replaces the per-model `{part}_to(device)` methods across all model classes,
plus scattered call sites in dataLoader/modelSetup/modelSampler/GenericTrainer,
with generic BaseModel methods driven by the existing ModelType.model_parts()
registry: materialize(*parts), evict(*parts), and materialize_only(*parts)
(evict everything else, then materialize the given parts - the swap-in/swap-out
pattern used throughout the Samplers and text-caching setup). eval() and
adapters() are likewise made concrete on BaseModel instead of hand-written per
model. Models whose component names diverge (Wuerstchen) or that have
components outside model_parts() (SD's depth_estimator, Anima's
text_conditioner) override the relevant methods directly.

Also fixes multi-TE samplers (Flux/SD3/SDXL/HiDream/HunyuanVideo) that
previously evicted all but the first text encoder and ran encode_text with
the rest still on temp_device.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
On CUDA, the layer-offload cache now uses one cache tensor instead of
the multi-chunk split: a large cuda allocation is page-mapped, so one
buffer packs with no inter-chunk tail waste, and the arena is filled
per-layer from the CPU so no full resident source coexists with it.
The host/pinned cache keeps the lazy multi-chunk split (its
peak-doubling justification is host-only).

Each layer-offload cache tensor, and each BaseModel component move,
gets its own dedicated torch.cuda.MemPool, so the churny small
tensors in the default pool can't wedge into a freed cache/component
segment and strand it across an evict/reload cycle -- the cross-cycle
fragmentation OOM on a tight budget. Pools are released once their
tensors are freed. Shared MemPool helpers (create_mem_pool,
mem_pool_context, supports_mem_pool) live in torch_util so both
BaseModel._move_part and the offload conductor use the same wrapper.

The alignment budget for the offload cache is sized from the actual
offload-tensor count (TENSOR_ALIGNMENT_BYTES per tensor) instead of a
fixed 4KB, since the unguarded ring wrap would otherwise silently
overwrite live weights once a cache tensor holds enough tensors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread modules/model/BaseModel.py Outdated
Squashed history of the mempool branch on top of PR Nerogar#1620 (Arena MemPool + single-buffer offload cache / materialize-evict API): eviction handling for multi-TE samplers, materialize_only_text_encoders() helper, generic BaseModel.eval()/adapters(), per-stem LoRA pooling, and review cleanups.
@dxqb dxqb added the preview merged in the preview branch label Jul 22, 2026
@dxqb dxqb mentioned this pull request Jul 23, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

preview merged in the preview branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant