ComfyUI-UniversalIO
Save/Load/Pass universal nodes for CONDITIONING & LATENT. Two-stage workflows for big models: batch encode → cloud sampling. Fixes path & XPU bugs; device auto/cpu/gpu; mode-based UI.
Nodes (2)
ComfyUI-UniversalIO
🧰 Universal Save/Load/Pass nodes for CONDITIONING & LATENT — refactored from
ComfyUI-SaveLoadUniversalConditioningLatent (4 nodes → 2), fixing its path & XPU bugs
and adding new features.
Nodes
| Node (search keywords) | Type | Directory |
|------|------|----------|
| 🧰 Universal Conditioning IO (Save/Load/Pass) | CONDITIONING | ComfyUI/models/conditionings/ (.bin) |
| 🧰 Universal Latent IO (Save/Load/Pass) | LATENT | ComfyUI/models/latents/ (.latent) |
Search Universal / Latent / Conditioning / IO. Category: UniversalIO.
Improvements over the original
| Fix / Feature | Description |
|-----------|------|
| 🐛 Path bug | Original comfy_root computation jumped one level up, saving files outside the engine dir; now uses official folder_paths.models_dir API |
| 🐛 XPU compat | Original torch.cuda.empty_cache() was a no-op on Intel Arc (XPU); now uses mm.soft_empty_cache() |
| 🐛 Cache pollution | Original recursive_cpu mutated class instances in place, corrupting ComfyUI cached outputs; now shallow-copies + replaces recursively |
| ✨ NestedTensor | Supports ComfyUI 0.30 video latent structure (comfy.nested_tensor.NestedTensor); auto device detection works |
| ✨ pass mode (default) | Pass-through, no save, no error |
| ✨ save_path | Custom filename; fixed name → overwrite-style save (no unlimited numbering) |
| ✨ auto_delete | Temp-file mode: deletes the old file before each save (disk keeps only the latest) |
| ✨ device | Save/load device: auto / cpu / gpu (see below) |
| ✨ UI visibility | Irrelevant parameters auto-hide per mode (JS web extension) |
Install
cd ComfyUI/custom_nodes
git clone https://github.com/hqh330/ComfyUI-UniversalIO.git
Restart ComfyUI, search UniversalIO category.
Usage
Parameters
| Parameter | Description |
|------|------|
| mode = pass (default) | Pass-through, no save, no error |
| mode = save | Save to the directory, output pass-through |
| mode = load | Load from file, output data |
| save_path | Custom filename (empty = auto-numbered Conditioning_NNNNN_.bin / Latent_NNNNN_.latent) |
| auto_delete | Delete old file before saving (with fixed save_path, disk keeps only the latest) |
| device = auto | Save follows the data's current device; load prefers GPU backend (XPU→CUDA→CPU fallback) |
| device = cpu (default) | CPU serialization/loading (most portable) |
| device = gpu | Force VRAM (XPU/CUDA; falls back to CPU with warning if no GPU) |
UI visibility (built-in)
Parameters auto show/hide when switching mode:
| mode | Visible | Hidden | |------|------|------| | pass (default) | mode, device | everything else | | save | mode, device, save_path, auto_delete | conditioning_file / latent_file | | load | mode, device, conditioning_file / latent_file | save_path, auto_delete |
Note: values of hidden parameters are preserved (display only, logic unaffected).
Outputs: data_out (CONDITIONING/LATENT) + filename (STRING, saved/loaded file name).
Load mode re-executes when file sha256 changes (IS_CHANGED); save/pass do not re-trigger.
Node is OUTPUT_NODE: save mode is an execution endpoint, so save-only workflows
(no downstream consumer) pass ComfyUI's "no outputs" validation.
File format: torch.save (serialized to CPU or VRAM per device, .bin / .latent).
Load supports files saved on any device (map_location auto-migrates).
Typical use case: two-stage workflow (VRAM saving)
For big models like H3 (TE 9.5GB + UNET 9.1GB + VAE 5GB > 16GB VRAM), use two stages:
Stage A (encode & save): TE encode → VAE encode → save (fixed name + auto_delete=True overwrite, or empty save_path for auto-numbered batch output) → exit/unload
Stage B (sample & render): load the saved conditioning/latent → load UNET + VAE only → sample → decode
Benefits: Stage B needs no TE (saves 9.5GB); .bin/.latent are pure CPU-serialized
files — upload to cloud and run Stage B on a big GPU (device=auto picks CUDA).
In-workflow two-stage: after Stage A save, chain an XPU-CacheClean (hard = unload all
models) and use its trigger_out universal link to guarantee Stage B runs after unload
(see ComfyUI-XPU-CacheClean).
Known limitations
conditioning_file/latent_filedropdowns cannot accept STRING links from other nodes (ComfyUI COMBO type limitation); select manually in GUI- Save with identical inputs may be skipped by ComfyUI's node cache; changing a parameter triggers execution
License
MIT