Nodes/ComfyUI-Apt_Preset/IO_Load_Tensor
ComfyUI Node

IO_Load_Tensor

Get a saved latent back — days later, in another workflow

By cardenluo·Created 2 years ago·Updated 3 days ago· 355
IO_Load_Tensor
  • initial_data
  • data
◄fold_name►
◄index0►
◄on_missingerror►

Sampling is the expensive part of a ComfyUI graph, and ComfyUI's cache only remembers it for as long as the session lives. Close the app, or change one widget upstream, and the latent you liked is gone. IO_Load_Tensor is the other half of the pack's disk-bridge: point it at a folder, tell it which file, and out comes the thing that was saved - a LATENT you can hand to a sampler, an IMAGE, a mask, audio, video, even a JSON blob.

How it works

Two inputs, both required. fold_name is a folder relative to output/Apt_brigeTensor/ - yes, the pack misspells "bridge" in the path and that's not your install being broken. Leaving it blank means the root of that folder. The code resolves the path and rejects anything that tries to escape the Apt_brigeTensor root, so no ../../ tricks.

index decides which file:

  • index = 0 - the newest file in the folder by modification time.
  • index > 0 - the file whose name carries that number. It matches the ..._00001_.safetensors style names IO_Save_Tensor writes (and a couple of legacy suffixes), so the first thing you ever saved is index 1, not 0.

Then it loads with comfy.utils.load_torch_file(..., safe_load=True, return_metadata=True) and rebuilds the payload from the metadata. That's the interesting part, because it makes this node read three different file families:

  1. Files written by IO_Save_Tensor, which carry a stage_payload descriptor - the full-fidelity path, preserving the data type (latent / image / mask / audio / video / json) and every tensor inside it.
  2. Files written by the flow_stage loop, which use the same descriptor format.
  3. ComfyUI's own core Save Latent output: a safetensors with a latent_tensor key. The loader handles the 0.18215 scaling those files use unless the file says latent_format_version_0, so you get a correct latent either way.

The single output is data - a wildcard type, because the whole point is that whatever's in the file comes back out.

Two behaviours that matter in practice. IS_CHANGED hashes the resolved file path and its mtime, so the node re-reads when the file on disk changes rather than serving a stale cached tensor - that's what makes "save, run, look, save again" work. But when it can't resolve a path it returns NaN, which is ComfyUI's idiom for "always dirty": a missing folder means the node re-executes on every queue, and everything behind it loses its cache too. A graph that suddenly feels slow is sometimes just this node pointed at a folder that isn't there.

A worked example

Split a heavy pipeline in two. Run A ends with IO_Save_Tensor saving the latent into fold_name = pass1. Run B starts with IO_Load_Tensor, same fold_name, index = 0, output straight into a KSampler with denoise around 0.4. You've just turned an hour-long graph into two fast ones you can iterate on independently.

The same trick covers the seed lottery: batch-sample ten latents, save them all, then load the winner later for an upscale pass without re-sampling the nine you didn't pick. Just note index = 0 gives you the latest - the numbering runs oldest-to-newest, so index = 1 is the first save in that folder.

Install

Manager → search Apt_Preset, or:

cd ComfyUI/custom_nodes
git clone https://github.com/cardenluo/ComfyUI-Apt_Preset.git
cd ComfyUI-Apt_Preset && pip install -r requirements.txt

On Windows, install-ComfyUI-Portable.bat in the pack root does the same install against the embedded Python. Restart after. This node lives alongside the rest of the pack, so you get the whole toolbox whether you wanted it or not - the requirements list is long (OpenCV, scipy, matplotlib, soundfile, and optional gguf/onnxruntime), and a dependency that didn't finish installing takes the pack down with an IMPORT FAILED line in the console.

Where it goes wrong

  • folder not found / no saved data in <folder> - the folder doesn't exist yet, or nothing has been saved into it. fold_name is relative to output/Apt_brigeTensor/, and a fresh install doesn't have your subfolder until IO_Save_Tensor creates it.
  • no saved data for file index N - you asked for a number that isn't there. Remember the numbering starts at 1.
  • does not contain supported bridge data - the file exists but is none of the three shapes above. Copying a random .safetensors (a checkpoint, a LoRA) into that folder and pointing at it is the classic version of this. Since this node only reads inside Apt_brigeTensor, even a core Save Latent file has to be copied in there first.
  • The output is a wildcard, so nothing validates you. Loading a mask and wiring it into something expecting a LATENT fails downstream with a much more confusing message than "wrong file".
CategoryApt_Preset/IO_Port

Inputs (4)

NameTypeDefaultDescription
fold_nameSTRING文件夹路径在 output/Apt_brigeTensor/。
indexINT00–9999index = 0:读取最新修改的文件;index > 0:寻找指定编号的文件。
on_missingCOMBOerrorfold_name 文件夹内无文件(首次 batch)时的行为:error=抛错;passthrough=返回 None;initial_data=返回 initial_data 槽位的种子。后续 batch 仍正常读盘上最新文件。
initial_dataopt*仅在 on_missing=initial_data 时生效。首次 batch 盘上无文件时返回该种子;后续 batch 仍读盘上最新落盘文件。

Outputs (1)

NameTypeDescription
data*—