🧹 XPU Cache Clean
The cache-clean node that actually works on Intel Arc — XPU_CacheClean
- trigger
- trigger_out
- report
If you run ComfyUI on an Intel Arc card, you've probably met this enemy: the first generation works, the second one dies with UR_RESULT_ERROR_OUT_OF_RESOURCES - Intel's level-zero error 40, which is just "you're out of VRAM but I can't tell you why." The usual culprit isn't your model. It's leftover buffers piling up in PyTorch's XPU caching allocator. XPU_CacheClean is a two-mode button for emptying that cache, written because the popular VRAM_Purge node quietly does nothing on Arc.
Why it had to exist
Here's the nasty bit that explains this whole pack. The cache-clean branch of the ram-vram-purge-windows VRAM_Purge node checks torch.cuda.is_available() before doing its cleanup. On XPU that call is always False, so on Intel Arc the cache cleanup silently never ran - the node only ever did the "unload all models" half of its job. So every Arc user got hard model unloads and zero cache cleaning, which is backwards: unloading models is the slow, disruptive part, and cleaning the allocator is the cheap fix. hqh330 wrote XPU_CacheClean to swap that logic around: XPU first, CUDA as a fallback, and it leans on ComfyUI's own comfy.model_management.soft_empty_cache(), which is already XPU-compatible. No intel_extension_for_pytorch, no extra dependencies - just torch, which you already have.
The two modes
One input matters, mode, and it's a dropdown with two options:
- soft - calls
torch.xpu.empty_cache(), keeps all models loaded. Warm start, essentially zero cost. This is the mode you sprinkle before VRAM-heavy stages like VAE decode or loading a big audio/TTS model. It fights allocator fragmentation, which is what actually causes the second-generation OOM. - hard - unloads every model, then soft-clears and runs
gc.collect(). This is the XPU-compatible replacement for VRAM_Purge. Use it at stage transitions: after a text-encoder pass you don't need again, before sampling a big model, between the save and load halves of a two-stage workflow.
The trigger trick
The optional trigger input accepts anything (* type) and passes it straight through unchanged - connect a wire just to force the node to run in a certain order. The trigger_out output is also *, and this is the part worth stealing: any node's * output can wire into any input of any node, which means you can use trigger_out purely as an execution-order guarantee, no data actually consumed. ComfyUI's execution order comes from links, not from where you draw the groups - groups are visual only. So in a two-stage workflow (Stage A: TE encode + save conditioning/latents → XPU_CacheClean in hard → Stage B: load + sample + decode), you run the hard clean line from Stage A's save, then hang trigger_out off any Stage B load node's input to make sure the unload finishes before Stage B touches VRAM.
The other output, report, is a STRING with free/used VRAM before and after, wired to any text-display node if you want the numbers on screen. If the driver won't report memory it degrades to a "can't read stats" line rather than crashing - fine, the clean still ran.
Install and reality check
cd ComfyUI/custom_nodes
git clone https://github.com/hqh330/ComfyUI-XPU-CacheClean.git
Restart ComfyUI and search "XPU Cache Clean". ComfyUI Manager can grab it too. No models to download, nothing to configure.
Be honest about scope: this node is small, new, and 0 impressions on comfy.icu. It's not a magic bullet - if a single generation itself genuinely exceeds your card, no empty_cache call saves you. But if your workflow runs once and then chokes, this is the first thing I'd wire in. On CUDA it still works as a fallback, but its reason for existing is Intel Arc - and that's a niche that shipped without this tool for far too long.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| mode | COMBO | soft | soft = 只清 allocator 缓存(热启动, 代价≈0);hard = 卸载全部模型 + 清缓存(下次用到重新加载) |
| triggeropt | * | 接任意线触发清理,数据原样透传。不接线也可独立执行。 |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| trigger_out | * | — |
| report | STRING | — |