mirror of
https://github.com/Comfy-Org/ComfyUI_Nvidia_VFX_Nodes.git
synced 2026-11-04 23:37:30 +00:00
[PR #36] [CLOSED] fix: free dlpack tensor per-frame to prevent GPU memory leak in RTX VSR node #40
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Comfy-Org/ComfyUI_Nvidia_VFX_Nodes#40
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/Comfy-Org/ComfyUI_Nvidia_VFX_Nodes/pull/36
Author: @CharlesMcquade
Created: 7/28/2026
Status: ❌ Closed
Base:
main← Head:fix/vsr-memory-leak📝 Commits (2)
77bc194fix: free dlpack tensor per-frame to prevent GPU memory leak in RTX VSR node71a5f69perf(vsr): avoid flushing CUDA cache per frame📊 Changes
1 file changed (+5 additions, -2 deletions)
View changed files
📝
__init__.py(+5 -2)📄 Description
The problem, from the user's seat
You drop a 200-frame video into ComfyUI, wire it through the
RTX Video Super Resolutionnode, hit Queue, and walk away. A minute laternvidia-smishows VRAM pegged at 100%, the ComfyUI prompt stops making progress, and the only way out is to kill the process. Short batches are fine — the node sings on 10 frames. It's only once you get past ~60 frames that it slowly suffocates.This is exactly what andypotato reported in #16: "When upscaling batches of images it will slowly eat up all my system memory. At some point it will start swapping and then spiral the system into swapping death loop. Usually it happens around 60 - 70 images upscaled." It's been open and reproducible for a while. Tracked in the new issue #35.
What's actually leaking
In
__init__.py, theexecute()loop callssr.run(input_frame)per frame and converts the returned dlpack tensor viatorch.from_dlpack():The problem:
torch.from_dlpack(dlpack_out)produces a PyTorch GPU tensor that shares the dlpack's underlying storage. Thedlpack_outvariable gets overwritten on the next iteration, but neither the dlpack capsule nor the PyTorch view that aliases it is ever explicitly released. The.movedim()/.unsqueeze()calls produce views, not new allocations, so the original per-frame storage stays pinned for the life of the loop. The CUDA caching allocator holds onto all of it, VRAM climbs monotonically, and eventually the node OOMs or deadlocks on a blocking CUDA call.The fix
Two changes to the per-frame loop, intended to release DLPack-backed storage each iteration without forcing a per-frame CUDA cache flush:
.clone()the converted tensor — breaks the aliasing so the output owns its own storage and the dlpack-backed tensor becomes immediately releasable.del dlpack_out, result, out_frame— drops the references this iteration instead of waiting for the frame to go out of scope.Verification
Tested locally with 100+ frame runs where the original code OOM'd around ~60 frames. With this patch VRAM stays flat across the whole run —
nvidia-smiholds a steady plateau instead of the old monotonic climb. Output is pixel-identical (.clone()is a copy, not a transform).Follow-up
71a5f69removes the per-frameempty_cache()in response to the review: the allocator can reuse released blocks without a forced flush each frame. The 100+ frame observation above was made on the prior version withempty_cache(); GPU memory behavior after its removal has not been re-measured, so that specific result is not claimed for the current head.Scope
__init__.pyCloses #35. Related: #16.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.