Nodes/Modal Sync/Modal Map Input
ComfyUI Node

Modal Map Input

The Pass-Through Node That Fans Your Batch Out Across Cloud GPUs

By ttulttul·Created 5 months ago·Updated 13 days ago· 7
Modal Map Input
  • value
  • value

The weirdest thing about Modal Map Input is that it does absolutely nothing - locally. Run it without the rest of the pack's machinery and it's a pure identity node: whatever goes into value comes out of value unchanged. All of the magic happens at queue time, when Modal Sync rewrites your workflow to run parts of it on Modal's serverless GPU cloud. It's a marker node, not a compute node, and understanding that is the whole game.

Modal Sync's model is "remote components": you mark nodes with Run on Modal, and the extension partitions them into islands that get shipped to a cloud worker, then stitches the outputs back into your local graph. By default a remote component runs once, preserving ComfyUI's normal zipped-batch behavior. Modal Map Input changes one thing: it tells the rewrite that a single boundary input should fan out across multiple Modal executions instead.

Here's the mechanism. Put this node in front of a remote-marked region on one input, and at queue time the rewritten component runs per-item:

  • Python lists become one item per element.
  • IMAGE batches, LATENT batches, and other batched tensors split on dimension 0.
  • Scalar primitives like a single INT or FLOAT become a one-item map.
  • Every other (non-mapped) boundary input is broadcast unchanged to every item.

The mapped outputs are then reassembled in item order, concatenating batchable tensors when possible and otherwise preserving an ordered list. Progress shows up as counts like 3/16 on the global status pill. That's it - one node, one fan-out dimension.

Why would you want this? Because Modal charges you by the GPU-second, and each cloud container handles one active execution at a time. Instead of burning a single A100 on 16 images in one serial batch, you fan the batch out and let Modal scale several containers in parallel (locally bounded by COMFY_MODAL_MAX_INFLIGHT_CALLS, default 4). For the workflows Modal Sync is aimed at - expensive tensor work, big models, slow samplers - that parallel win is the entire point. Think "16 seeds through a heavy remote sampler" or "a batch of 8 images through an upscaler" rather than "one image slightly faster."

The node itself has exactly two sockets worth knowing:

  • value (input, type *) - the boundary input to fan out. A list or batched tensor triggers per-item mapping; anything else passes through.
  • value (output, type *) - the reassembled result, wired to whatever was consuming the input.

Installation is the pack install, since this ships inside it: ComfyUI Manager, search "Modal Sync" (ttulttul/ComfyUI-Modal), or clone into custom_nodes/ and restart:

cd ComfyUI/custom_nodes
git clone https://github.com/ttulttul/ComfyUI-Modal

For remote execution you'll also need Modal credentials (python -m modal setup in your ComfyUI venv); the extension installs the pinned modal==1.4.2 SDK for you on startup if it's missing. There's also a local mode (COMFY_MODAL_EXECUTION_MODE=local) that exercises the rewrite without spending money - genuinely useful for learning this node before you point it at the cloud.

Now the traps, straight from the source:

  • One mapped boundary per remote component. More than one Modal Map Input in a single component fails queue-time validation.
  • The mapped input must feed only Modal Map Input nodes. If the boundary input also connects somewhere else, the rewrite rejects it. Route it through this node alone.
  • Only transportable values can cross the boundary. IMAGE, MASK, LATENT, SIGMAS, NOISE, INT, FLOAT, BOOLEAN, STRING are fine. MODEL, CLIP, VAE, CONDITIONING are not - the pack either expands the remote island upstream to cover their producer or fails with a boundary error. The right-click Modal > Enable on Upstream Nodes action handles the common case.

And the bill. This is the node where "ooh, parallel" and "uh oh, money" collide. Each mapped item can mean another GPU container, so a 16-item fan-out is potentially 16 concurrent A100s. Warm containers scale down after 600 seconds by default, but the charges don't just vanish - start in local mode to sanity-check the graph, then run one small mapped batch remotely before you let it rip. It's a genuinely clever little adapter; just respect the dial.

CategoryModal

Inputs (1)

NameTypeDefaultDescription
value*

Outputs (1)

NameTypeDescription
value*