◈ Attention Couple (Illustrious)
Multi-concept control without building a mask chain
- model
- positive
- negative
- mask
- latent_image
- model
- positive
- negative
- report
The pack ships two ways to do regional control: IllustriousRegionalConditioning, which builds a list of masked prompts through a chain of nodes, and this one, which does something lower-level - it patches the model's attention directly using a single spatial mask, no region-list building required.
What "attention couple" actually means
The name is a real lineage, not marketing. Attention Couple started as a Forge extension, following Latent Couple before it, and every generation of this technique has had to be rebuilt from scratch for each new architecture because it works by masking attention at a specific layer structure that doesn't port between models. This node is the Illustrious/SDXL-specific rebuild.
There are two ways to mask attention, and they trade off against each other: masking the cross-attention (text) tokens keeps regions aware of each other but sets loose bounds that leak past the mask edge; masking the self-attention (image) tokens holds the bounds tight but leaves each region ignorant of what's happening elsewhere, which can produce uneven composition. This node works at the image-token level - it's the tighter-bounds, more-surgical option - which is why affect_down, affect_mid, and affect_up exist: they let you choose which UNet stages get patched. Down blocks shape broader structure, up blocks shape finer detail, so narrowing which stages you affect narrows where the coupling actually shows up.
The inputs and outputs that matter
model,positive,negative- required.mask(IMAGE, not MASK - a spatial 0–1 map) - white strengthens attention in that area, black leaves it alone. Optional, but the node does nothing useful without one.latent_image(optional) - feed it in so the node can infer the exact UNet grid size and align the mask precisely; skip it and alignment is looser.strength(default 0.5, 0–1) - a genuine blend dial, not a switch: 0 is no effect, 1 is full masked coupling. This is the one to reach for before disabling blocks.token_filter- the tooltip says it plainly: reserved for future token-level gating, not implemented yet. Leave it empty; setting it does nothing right now.
Outputs: patched model, passthrough positive/negative, and report - a diagnostic string, worth checking (alongside advanced_logs) if coupling doesn't seem to be taking effect.
Installing it
ComfyUI Manager: search "EasyIllustrious," install, restart. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/regiellis/ComfyUI-EasyIllustrious
pip install -r ComfyUI-EasyIllustrious/requirements.txt
No model downloads - it's a model-patching node against your existing checkpoint.
Common issues
Composition looks uneven or oddly split. This is the documented cost of image-token masking, not a bug - the technique holds region bounds tightly at the price of regions not "seeing" each other. Lower strength before assuming something's broken; the effect is a dial, and 1.0 is a strong setting, not the recommended starting point.
No visible effect at all. Check that mask is actually connected - it's optional at the schema level, so a missing wire fails silently. Also confirm latent_image is wired if your results seem misaligned with the mask you painted; without it the node has to guess the grid size.
Wondering whether to use this or IllustriousRegionalConditioning. If you're building distinct prompts per named region, use Regional Conditioning - it's built for exactly that with prompt-per-mask scheduling. Reach for Attention Couple when you want lower-level, single-mask control over how strongly attention favors one area, without building out a full region list.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| positive | CONDITIONING | — | |
| negative | CONDITIONING | — | |
| maskopt | IMAGE | Spatial mask (NHWC 0..1). White strengthens attention; black leaves unchanged. | |
| latent_imageopt | LATENT | Optional latent to infer UNet grid size for precise mask alignment. | |
| affect_downopt | BOOLEAN | true | Apply coupling to Down blocks. |
| affect_midopt | BOOLEAN | true | Apply coupling to Mid block. |
| affect_upopt | BOOLEAN | true | Apply coupling to Up blocks. |
| strengthopt | FLOAT | 0.500–1 | Blend strength per position: 0=no change, 1=full masked coupling. |
| token_filteropt | STRING | Reserved: token-level gating (not used yet). Leave empty. | |
| advanced_logsopt | BOOLEAN | false | Print patching details to console. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| model | MODEL | — |
| positive | CONDITIONING | — |
| negative | CONDITIONING | — |
| report | STRING | — |