Nodes/ComfyUI-ppm/Attention Couple (PPM)
ComfyUI Node

Attention Couple (PPM)

Different prompts for different regions

By pamparamm·Created 2 years ago·Updated about 19 hours ago· 265
Attention Couple (PPM)
  • model
  • base_cond
  • base_mask
  • MODEL

Two characters in one image and their features keep bleeding into each other - the redhead ends up with a streak of the other one's blue, the swords swap hands, everyone's outfit turns into a blend. That's not you prompting wrong. Conditioning is global: one prompt describes the whole canvas, so the model has no idea which subject owns which trait. Attention Couple is the standing fix. You paint (well, box) a region for each subject and hand each region its own prompt.

Why this exists and where it fits

Regional prompting has been a live need since 2023 and it's never gone away - steady at 20-40 threads a month for three years, which is what a genuinely unsolved problem looks like. The tooling churns constantly because every new architecture breaks the old implementation, so the name in any given guide dates it: Latent Couple → Regional Prompter → Forge Couple → and now purpose-built nodes like this one. Attention Couple is the "attention-masking" generation, and it's the implementation later work gets measured against.

ppm's version is a modified port of the Attention Couple by laksjdjf and Haoming02 (the Forge Neo maintainer), rebuilt to be more compatible with other custom nodes. Mechanically it masks cross-attention per region: each region's prompt only "wins" inside its box, so subjects stop stealing each other's attributes. It supports SD1, SDXL, and Anima.

How you actually wire it

This is the part that trips people, so slow down here. The node has these inputs:

  • model (MODEL) - your model, patched
  • base_cond (CONDITIONING) - this is the important one. Link it to the same positive conditioning you feed your KSampler/SamplerCustom. It's the "everything else / global" prompt.
  • base_mask (MASK) - the mask for that base region.

The regional inputs are dynamic - they don't show up until you use them. Attach a region's cond and mask and a fresh cond_ / mask_ pair appears, ready for the next region. So the flow is: encode a prompt per subject, build a mask per subject, plug them in, and the node grows to fit. Output is a single patched MODEL you send to your sampler.

For the masks, the natural partner is LatentToMaskBB (also in this pack) - it gives you box coordinates relative to your latent, so x=0.5, y=0.0, w=0.5, h=1.0 is "the right half." Stack a couple of those and you've got left-character / right-character in about thirty seconds. Want to push a region harder or softer? Adjust its mask value, or drop a ConditioningSetAreaStrength on that region's cond.

The ordering rule that matters

Straight from the README: connect Attention Couple after other model patches. If you're also running CLIPNegPip, EasyCache, LazyCache, or similar, those go first and Attention Couple goes last in the patch chain. Get the order wrong and you'll get subtle wrongness rather than a clean error, which is the worst kind of bug. There's a ready-made attention_couple+negpip template in Browse Templates → Custom Nodes → ComfyUI-ppm that shows the correct wiring - start from it.

Install

Nothing special, no model files:

  • ComfyUI Manager: search "ComfyUI-ppm", install, restart.
  • Manual: cd ComfyUI/custom_nodes && git clone https://github.com/pamparamm/ComfyUI-ppm, restart.

Honest take and gotchas

Attention Couple is the right tool, but know its limits. Cross-attention masking keeps regions aware of each other (good for coherent composition) but the bounds leak a bit - a hard seam-free split isn't guaranteed. That's inherent to the text-token approach, not a bug in ppm's port. If you want zero attribute bleed you're fighting physics; if you want "these two characters mostly stay themselves," it delivers.

Also worth knowing: asagi4's comfyui-prompt-control has its own attention-couple with a prompt-based syntax, so you don't add a cond/mask node per region - the README itself points you there if the node-per-region approach feels clunky. On modern LLM-encoded models (Z-Image, Flux, Anima) prompt adherence is good enough that you may not need regional prompting at all for simpler scenes; reach for this when word-order tricks stop cutting it. And the pack rule: erroring after an update? Delete the node and re-add it.

Categoryadvanced/model

Inputs (3)

NameTypeDefaultDescription
modelMODEL
base_condCONDITIONINGPositive conditioning from KSampler/SamplerCustom node. Can be optionally scaled up/down by using ConditioningSetAreaStrength node.
base_maskMASK

Outputs (1)

NameTypeDescription
MODELMODEL