Nodes/ComfyUi-MpiNodes/Mpi Stage Latents
ComfyUI Node

Mpi Stage Latents

The two-stage latent handshake, collapsed into one node

By MadPonyInteractive·Created 11 months ago·Updated 5 days ago· 3
Mpi Stage Latents
  • latent
  • denoised
  • latent
  • denoised
is_continuefalse
is_previewfalse
save_pathmpi_stage1
load_pathmpi_stage1

A multi-stage video workflow used to need a small army of nodes: save the stage-1 latent, load it back for stage 2, plus a couple of boolean inverters, an if/else, a blocker, and a compare node to gate it all - the pack's own source lists eight nodes this one replaces. MpiStageLatents is that whole dance in a single node, driven by two widgets: is_continue and is_preview.

The naming tells you what it's for. Stage 1 is a cheap, low-res pass; stage 2 continues from the saved latent at full res or higher quality. The hard part has always been making the two stages not fight - on a preview run you want to stop after stage 1 and look at it, on a continue run you want to skip stage 1 entirely and start from the saved file. This node makes all three modes one widget flip:

  • Full single run (is_continue off, is_preview off) - latent passes through, gets saved.
  • Preview (is_preview on) - saves stage 1, releases the denoised output for the preview decode, blocks latent so stage 2 doesn't follow.
  • Continue (is_continue on) - loads load_path and returns it as latent, saves nothing.

The load-bearing mechanism

The subtle part is the lazy inputs. The node's check_lazy_status refuses to request its latent inputs at all when is_continue is on - so the stage-1 sampler upstream is genuinely skipped, not run-and-discarded. An ExecutionBlocker only gates what's downstream; this lazy-request trick is what stops the sampler from running in the first place. That's the difference between a fast continue and a workflow that silently re-renders stage 1 every time.

The two latents are also handled right: it survives the packed audio+video latents of video models like MiniMax H3, which crash core's Save/Load Latent nodes with a NestedTensor reshape error. And if a continue finds no file at load_path, it raises a loud FileNotFoundError instead of quietly blocking every branch and finishing with zero output - the "dead button" failure the author explicitly fixed.

The inputs that matter

  • is_continue - stage 2. Widget, not a wire.
  • is_preview - stop after stage 1. Widget. Ignored when is_continue is on.
  • save_path / load_path - where stage 1 writes / what a continue reads. Absolute paths used as-is; bare names resolve to <output>/latents/ (save) and the engine <input>/ folder first (load).
  • latent / denoised (optional) - the stage-1 outputs.

Install

Part of ComfyUi-MpiNodes. ComfyUI Manager (search "MpiNodes" / publisher "mad-pony-interactive"), or:

cd ComfyUI/custom_nodes
git clone https://github.com/MadPonyInteractive/ComfyUi-MpiNodes

Restart. No extra dependencies.

Where people trip

The switches are widgets, not wired inputs - a host app (like Cubric Vision, which this pack powers) drives them by node_title.is_continue, but in a hand-built graph you flip them by hand, so it's on you to set is_continue on the run where the file already exists. Miss it and the node happily re-runs stage 1. And remember the failure mode is deliberately loud: a missing latent raises. That's better than silent, but it does mean your stage-2 file has to be exactly where load_path points, or the run dies on purpose.

CategoryMpiNodes/Latent

Inputs (6)

NameTypeDefaultDescription
is_continueBOOLEANfalseStage 2. Loads `load_path` and returns it as `latent`; nothing is saved and — because the latent inputs are lazy — the stage-1 sampler upstream never runs at all.
is_previewBOOLEANfalseStop after stage 1. Saves the latent and releases `denoised` for the preview decode, blocking `latent` so stage 2 does not run. Ignored when is_continue is on.
save_pathSTRINGmpi_stage1Where stage 1 writes. Absolute path used as-is; a bare name goes to <output>/latents/<name>.latent, overwriting.
load_pathSTRINGmpi_stage1What a continue reads. Absolute path used as-is; a bare name is looked up in the engine <input>/ folder first (where a host app stages it), then <output>/latents/.
latentoptLATENT
denoisedoptLATENT

Outputs (2)

NameTypeDescription
latentLATENT
denoisedLATENT