Nodes/ComfyUI-TiledAttentionCouple/Tiled Attention Couple
ComfyUI Node

Tiled Attention Couple

Two characters, one image, and nobody's hair color swaps

By Deathspike·Created about a year ago·Updated 10 months ago· 8
Tiled Attention Couple
  • model
  • clip
  • config
  • model
  • positive
  • negative
width512
height512

You know the failure mode. You type "two girls, one in a red dress, one in a blue dress" and the sampler hands you two girls wearing the same mauve. Multi-subject prompts bleed: the model attends to one global text embedding, so both characters inherit bits of each other. Tiled Attention Couple exists to fix exactly that - split the canvas into strips and give each strip its own prompt, so the left third stays firmly red-dress while the right third stays blue.

This node is the heart of the pack. Its siblings - the Config node where you write the prompts, the Shuffle node, the Impact Pack Detailer hook - all feed into it or hang off it. This is the one that actually changes how attention works.

What it does under the hood

Tiled Attention Couple is a ComfyUI port of laksjdjf's attention-couple approach, which itself descends from the Forge Couple / Attention Couple lineage. It works by patching the cross-attention layers of the UNet (the attn2 blocks, where text tokens meet image tokens). Instead of every pixel attending to one full prompt embedding, each pixel attends to the embeddings whose tile mask covers it.

The masks are built from the division string in your config: 1,1 becomes two binary masks, 1,2 becomes one mask a third of the width and one mask two-thirds. The common prompt (before the first BREAK) gets a full-canvas mask and applies everywhere; each tile prompt is gated to its own region. During sampling, each region's attention output is computed against its own text, masked, and summed back together.

Worth knowing: this is the text-token flavor of regional conditioning, not the image-token masking some newer packs use. That means regions stay aware of each other, which helps composition, but the bounds are loose - expect some attribute bleed at the tile borders. It's a middle-ground technique, and the seams are more visible when tiles are small or prompts are close. For SD1.5 and SDXL UNets it works out of the box; like all attention-patching tricks it does not port to other architectures (Flux, Anima, and friends need their own regional nodes).

Inputs and outputs that matter

  • model - your checkpoint's model, straight from the loader.
  • clip - the matching CLIP, also from the loader. The config is encoded against this.
  • config - a TILED_CONFIG from the Tiled Attention Couple (Config) node. Nothing works without it.
  • width / height - the pixel dimensions of your generation, and the one place beginners trip. They must match what your EmptyLatentImage is set to, and each must be divisible by the model's latent size (32 for SD1.5-class, 64 for SDXL-class). Get it wrong and the node raises Width must be divisible by 32. rather than quietly misbehaving, which is honestly polite of it.

Outputs are model, positive, and negative conditionings - wire all three into the KSampler. The returned model is a patched clone, so your loaded model is untouched.

The wiring

The README's setup is four steps and it's accurate:

  1. Replace your normal positive/negative text with the Config node.
  2. Add this node, set width/height to match your latent.
  3. Connect Config → this node.
  4. Feed it a model and clip; use its model/positive/negative outputs downstream.

Installing it

cd ComfyUI/custom_nodes
git clone https://github.com/Deathspike/ComfyUI-TiledAttentionCouple

Restart ComfyUI. ComfyUI Manager also works - search "Tiled Attention Couple". There are no extra Python dependencies (dependencies = [] in its pyproject), no model files to download, and no API keys. It's pure attention patching over whatever checkpoint you already have. The author showcases it with their own anime checkpoint (NanoMix v13), but any SD1.5 or SDXL model works.

Where people get burned

  • Resolution mismatch. width/height that don't match your actual generation mean the tile masks are built for the wrong canvas, and your regions drift off their intended spots. Match them to EmptyLatentImage.
  • Expect borders, not walls. Because this masks text tokens rather than image tokens, it stops the worst bleeding but won't give you a hard cut. If you need razor-sharp region boundaries, you're in image-token-masking territory - different pack, same underlying idea.
  • It's SD1.5/SDXL only. The patch targets specific UNet block indices; newer architectures ignore it entirely and you'll just get a normal generation with no coupling.
Categoryconditioning

Inputs (5)

NameTypeDefaultDescription
modelMODEL
clipCLIP
configTILED_CONFIG
widthINT5120–16384
heightINT5120–16384

Outputs (3)

NameTypeDescription
modelMODEL
positiveCONDITIONING
negativeCONDITIONING