by.waclaw.online / spark / video / 02

ComfyUI on GB10 That Doesn't Run Out of Memory

Why a 128 GB machine appears to cap out at 64, the launch flags that fix it, attention kernels built for sm_121a, and a model library that lives on external storage.

Series 3, article 2 of 4 · written 31 July 2026

There is a well-travelled forum thread titled, roughly, "buyers beware: DGX Spark limited to 64 GB in ComfyUI." It is not a hardware limitation and it is not a defect. It is what happens when an application written for discrete GPUs meets unified memory, and it is fixable with configuration. This article is that configuration.

What is actually going wrong

On a normal machine, model weights live in system RAM briefly and then move to separate video memory. ComfyUI's loader memory-maps a checkpoint, which counts against "CPU" memory, and then hands it to the GPU, which counts against "GPU" memory. Two pools, two accountings, no conflict.

On GB10 there is one pool. The mapped file and the device-resident copy are the same 128 GB, counted twice — so a 42 GB checkpoint can consume 84 GB of budget and you hit a wall at what looks like half your memory. Add a kernel page cache still holding the previous model and the wall arrives sooner.

The corollary is that flags which help on a discrete card actively hurt here:

FlagOn a discrete GPUOn GB10
--gpu-onlyKeeps everything in VRAM, avoids transfersHarmful. Fights the unified allocator, breaks eviction, causes easy OOM
--disable-mmapSometimes helpsHarmful. Forces a full read-and-copy of a very large checkpoint at load
Pinned host memoryFaster host-to-device transferPointless. Host and device are the same DRAM
Global --fp16-vaeSaves memoryAvoid — let ComfyUI pick dtype per model

The fast path: a prebuilt GB10 image

Two community projects have solved this and published the results. Unless you enjoy compiling attention kernels, start with one of them.

A pre-bundled image ships ComfyUI with CUDA 13.0.2, PyTorch 2.9.1+cu130 for ARM64, SageAttention v3 compiled with explicit Blackwell SASS for sm_121a, NVFP4 acceleration through CUTLASS, around 1,700 backend nodes and 16 custom node packs, plus LTX-2.3 22B, Flux 2 Dev and ACE-Step v1.5 XL Turbo pre-staged. Setup is roughly 50 minutes, most of it downloading about 285 GB of weights.

# Roughly: generate a Hugging Face read token, accept the gated model
# licences on HF, then
git clone https://github.com/AEON-7/comfyui-aeon-spark
cd comfyui-aeon-spark
./setup.sh            # asks for the HF token, then downloads ~285 GB

An optimisation kit takes the opposite approach: keep your own ComfyUI installation and apply GB10-specific patches and a tuned launcher to it. This is the better option if you already have workflows and custom nodes you care about.

cd $HOME/ComfyUI && git pull
git clone https://github.com/Triplany/comfyui-dgx-spark
cd comfyui-dgx-spark
bash install.sh
bash verify.sh
bash $HOME/ComfyUI/run_dgx_spark.sh

Its patches are version-aware and self-disabling as upstream catches up. One is worth knowing about by name: a NaN/Inf clamp before AAC encoding, which prevents LTX-2.3 audio from crashing the workflow at the final step. If you install ComfyUI by hand and find that audio-generating workflows die during encoding, that is what you are missing.

The launch configuration

Whichever route you take, these are the settings that matter. If you are writing your own launcher, this is it:

#!/usr/bin/env bash
# /opt/spark/comfy/run.sh

# Let the unified allocator manage memory instead of PyTorch's caching allocator
export PYTORCH_NO_CUDA_MEMORY_CACHING=1

# Model library on external storage
export HF_HOME=/mnt/models/hf

# Reclaim page cache the kernel is holding from the previous session
sync; echo 3 | sudo tee /proc/sys/vm/drop_caches >/dev/null

python main.py \
  --listen 0.0.0.0 \
  --port 8188 \
  --reserve-vram 8 \
  --disable-pinned-memory yes \
  --preview-method auto
SettingWhy
PYTORCH_NO_CUDA_MEMORY_CACHING=1PyTorch's caching allocator hoards freed blocks. On a shared pool that starves everything else. Turning it off costs a little speed and buys a great deal of stability.
--reserve-vram 8Headroom for activations so a peak during sampling does not take the process out. The prebuilt image defaults to 2; 8 is safer for 22B video work with audio.
--disable-pinned-memory yesPinned host memory is meaningless when host and device share DRAM, and it hurts here.
--listen 0.0.0.0Reachable from the rest of the LAN. See the warning below.
No --gpu-only, no --disable-mmap, no global dtype flagsSee the table above. The absence of these is as important as the presence of the others.
torch.compile is off, deliberately. On sm_121a, Triton does not currently emit working machine code, so compilation either fails or produces something slower. Workflows offering a "compile" node should have it bypassed on this hardware. SageAttention, compiled with explicit Blackwell SASS, is where the attention speedup comes from instead.

The model library

Do not let ComfyUI's models/ directory be the canonical store. Point it at your library instead, so the same weights serve ComfyUI, a diffusers script and anything else without duplication.

# $HOME/ComfyUI/extra_model_paths.yaml
spark:
    base_path: /mnt/models/comfy/
    checkpoints:     checkpoints/
    diffusion_models: diffusion_models/
    text_encoders:   text_encoders/
    vae:             vae/
    loras:           loras/
    clip_vision:     clip_vision/
    upscale_models:  upscale_models/

The trade-off from the hub page applies directly. External storage costs load time, not generation time: once weights are resident, where they came from is irrelevant. So keep the checkpoint you are actively iterating on internal, and let the archive live outside. With video models at 40 GB apiece, that difference is minutes per swap.

Verifying you got the acceleration

Silent CPU fallback and missing kernels look identical to "slow." Check explicitly.

# Inside the ComfyUI environment
python - <<'PY'
import torch
print("torch      :", torch.__version__, "| cuda:", torch.version.cuda)
print("device     :", torch.cuda.get_device_name(0))
print("capability :", torch.cuda.get_device_capability(0))   # expect (12, 1)
try:
    import sageattention; print("sageattention: present")
except ImportError:
    print("sageattention: MISSING — attention will be slow")
PY

Then run one small generation and watch the pool from another terminal:

watch -n1 'free -g; echo; nvidia-smi --query-gpu=utilization.gpu,memory.used --format=csv'

What you want to see is used memory rising to something sensible for the model and staying there, with GPU utilisation high during sampling. What you do not want is memory climbing steadily across successive runs — that is the eviction problem, and it means a flag is wrong or the page cache needs dropping.

Running it as a service

# /etc/systemd/system/comfyui.service
[Unit]
Description=ComfyUI
After=network-online.target

[Service]
Type=simple
User=YOUR_USER
WorkingDirectory=/home/YOUR_USER/ComfyUI
Environment=PYTORCH_NO_CUDA_MEMORY_CACHING=1
Environment=HF_HOME=/mnt/models/hf
ExecStartPre=/bin/sh -c 'sync; echo 3 > /proc/sys/vm/drop_caches'
ExecStart=/home/YOUR_USER/ComfyUI/venv/bin/python main.py \
  --listen 0.0.0.0 --port 8188 --reserve-vram 8 --disable-pinned-memory yes
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

The ExecStartPre cache drop needs root; either run the unit as root with User= removed, or grant the specific command through sudoers. It matters more than it looks — restarting ComfyUI after a large model without clearing cache is a reliable way to hit a memory wall on the first generation.

--listen 0.0.0.0 exposes an unauthenticated ComfyUI to your whole network. ComfyUI executes arbitrary workflow graphs, can read and write files, and custom nodes run with the server's privileges. On a trusted home LAN this is a reasonable trade and it is the deployment these articles assume. It is emphatically not something to expose beyond that. If your network has guest devices on it, bind to 127.0.0.1 and reach it over an SSH tunnel: ssh -L 8188:localhost:8188 spark.local.

When it still misbehaves

SymptomCause and fix
OOM at roughly half of memoryThe double-counting problem. Check for --gpu-only, drop the page cache, confirm PYTORCH_NO_CUDA_MEMORY_CACHING=1.
Workflow dies during audio encodeThe NaN/Inf-before-AAC bug in LTX-2.3 audio. Apply the optimisation kit's patch.
Memory grows across generations until it failsBroken cache eviction — usually --gpu-only. Restart between heavy jobs as a workaround.
First generation takes foreverKernel compilation and cache population. Expected; roughly 3× faster afterwards.
Custom node fails to import with a CUDA errorA node package built against CUDA 12 or x86_64. Check whether a GB10-aware fork exists before trying to fix it.
Everything is slow but nothing errorsRun the verification script. Missing SageAttention or a CPU Torch build.

With this working, the interesting part starts: generating clips.

Sources