You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The MPS branch of AutoTorchModule.check_free_vram() builds a tuple whose [1] - [0] is free memory, but the shared line below it treats that value as used memory. The CUDA/NPU branch is correct; only the MPS branch is inverted, so vram_limit behaves backwards on Apple Silicon.
so promotion is disabled while VRAM is free and enabled once it fills up — the opposite of the intent. Setting vram_limit the way the examples do for CUDA (total - 2) reduces to allocated > 2 GB, i.e. every layer is promoted and pinned from early in the first denoising step onward, and VRAM management stops bounding anything. On a 64 GB M1 Ultra running DiffSynth-Studio/MiniMax-H3-NF4 this drove the process into swap; one run was killed by jetsam mid-generation.
The current workaround is to pass vram_limit=None, which short-circuits the predicate — but that also disables the promotion heuristic entirely rather than fixing it.
Suggested fix
Make the MPS tuple mirror mem_get_info()'s (free, total) shape so the shared arithmetic stays valid:
Investigated and drafted with Claude Code. The reproduction output and the code references above were produced on the machine described in Environment.
Summary
The MPS branch of
AutoTorchModule.check_free_vram()builds a tuple whose[1] - [0]is free memory, but the shared line below it treats that value as used memory. The CUDA/NPU branch is correct; only the MPS branch is inverted, sovram_limitbehaves backwards on Apple Silicon.DiffSynth-Studio/diffsynth/core/vram/layers.py
Lines 65 to 72 in b1c02ce
torch.cuda.mem_get_info()returns(free, total), so[1] - [0] == total - free == used. Correct.(current_allocated, recommended_max), so[1] - [0] == recommended_max - allocated == free. Inverted.Reproduction
With 62 MB in use the function reports 51.8 GB used.
Consequence
forward()promotes a layer to the preparing device whencheck_free_vram()is true:DiffSynth-Studio/diffsynth/core/vram/layers.py
Lines 546 to 547 in b1c02ce
Substituting the inverted value, the predicate
used_memory < vram_limitbecomesso promotion is disabled while VRAM is free and enabled once it fills up — the opposite of the intent. Setting
vram_limitthe way the examples do for CUDA (total - 2) reduces toallocated > 2 GB, i.e. every layer is promoted and pinned from early in the first denoising step onward, and VRAM management stops bounding anything. On a 64 GB M1 Ultra runningDiffSynth-Studio/MiniMax-H3-NF4this drove the process into swap; one run was killed by jetsam mid-generation.The current workaround is to pass
vram_limit=None, which short-circuits the predicate — but that also disables the promotion heuristic entirely rather than fixing it.Suggested fix
Make the MPS tuple mirror
mem_get_info()'s(free, total)shape so the shared arithmetic stays valid:Either that, or compute
used_memoryper branch instead of sharing one expression.Environment
b1c02ce(currentmain); the MPS branch is unchanged since it was added in support run minimax-h3 on MPS #1559DiffSynth-Studio/MiniMax-H3-NF4(FL2VA),device="mps"Related
vram_limit is not taking effecton CUDA. Different root cause, same function; worth considering together.mem_get_info()for devices lacking it, but does not touch the arithmetic; it now overlaps with the MPS branch added by support run minimax-h3 on MPS #1559.Investigated and drafted with Claude Code. The reproduction output and the code references above were produced on the machine described in Environment.