😺NKD Klein Reference Control
Strength, a curve, and a region
- model
- mask
- latent
- model
- latent
Of the pack's three "control" nodes, NKD Klein Reference Control is the one that does it all. Strength, a per-step curve, and - if you connect a mask - regional confinement, for one reference, in a single node. No mask connected and it's just a clean strength control; connect one and it turns into a regional control too. One node per reference, chained on the model line between Presampling and your sampler.
It's marked experimental, like its siblings in the regional family. It works, with the usual experimental caveat: on strong settings you can expect a little bleed into neighboring areas. The author says so on the tin, so treat it as "try it, keep the settings sane."
How it works
Klein appends each reference as extra tokens at the end of the attention sequence ([txt | canvas | ref_0 | ref_1 …]). This node installs a single attention patch that does two things at once:
- Global strength - scales the reference's key/value tokens up or down, the same lever as the standalone Reference Weight node (1.0 = no change, below 1 dilutes, above 1 reinforces up to 2). A connected
schedulecurve multiplies this per denoise step. - Regional confinement - when a
maskis connected, it adds a per-position bias on the canvas-query × this-reference-key attention block: canvas tokens outside your zone get pushed away from that reference, tokens inside get neutral or boosted attention. That's how the influence stays inside the zone - the mechanism is resolution-independent because it works on the model's token grid.
Because both effects ride one patch, they compose cleanly: you can keep a reference strong overall and confined to one zone.
Inputs that matter
- reference_index - which reference this controls.
0is ref_0,1is ref_1, in connection order. Usually you'll want a secondary reference (1+). - weight - overall strength, up to 2. With a curve, it's multiplied per step (a 1→0 curve runs it down to "removed").
- mask (optional) - the zone to confine it to. Leave unconnected for a pure strength node; connect it and the regional controls wake up.
- latent (optional, but needed with a mask) - the canvas latent from Presampling, used to map your mask onto the token grid. Chain it from the previous Reference Control's latent output.
- region_weight - how strongly the reference shows up inside the zone (1 = normal, up to 4 reinforces). Watch it: pushed high, it can bleed outside.
- outside_suppression - how much the reference is held back outside the zone. 1 = only inside; 0 = no restriction.
- region_hardness - crispness of the zone edge. 0 = soft falloff that follows your mask's blur; 1 = hard binary edge (tightest containment, but the boundary snaps to the token grid and can look slightly stepped). Raise this when the reference bleeds into areas you didn't mask.
Outputs are model and latent - the latent is passed through so you can chain several Reference Control nodes to drive multiple references, each with its own zone.
Wiring it up
NKD Klein Presampling → NKD Klein Reference Control → [your sampler] → NKD Klein Postsampling
Connect Presampling's model and latent in, set the index, add a mask if you want the zone, and run. If you only ever need strength (no region), the slimmer Reference Weight node is the simpler grab - but if there's any chance you'll want the mask later, starting with Control saves you a rewrite, since it's the superset.
Installing
Search NKD Klein Tools in ComfyUI Manager, or:
cd ComfyUI/custom_nodes
git clone https://github.com/Nekodificador/ComfyUI-NKD-Klein-Tools
Restart ComfyUI. No external pip dependencies - the pack's requirements.txt is empty, so no dependency conflicts to fight. You supply the Flux Klein model yourself (4B or 9B with its Qwen3 encoder and VAE); the pack adds no weights.
Gotchas
- Empty or all-black mask → no-op. The node logs a warning and passes the model through unchanged rather than accidentally blocking the reference everywhere.
- Mask but no latent. It can't map the mask to the token grid, so it applies strength only and skips the region - the warning in the console tells you.
- Bleed on strong settings. That's expected on high
region_weight; tighten withregion_hardnessinstead of dialing everything else up.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| reference_index | INT | 10–7 | Which reference this node controls. 0 = the main reference (ref_0), 1 = ref_1, … in the order added. |
| weight | FLOAT | 1.000–2 | Overall strength of this reference. 1.0 = no change, below 1 dilutes (0 = removed), above 1 reinforces (up to 2). A connected curve multiplies this per step. |
| region_weight | FLOAT | 1.000–4 | (Regional) how strongly the reference shows up INSIDE the zone. 1.0 = normal, up to 4 reinforces. Only used with a mask. |
| outside_suppression | FLOAT | 1.000–1 | (Regional) how much the reference is held back OUTSIDE the zone. 1.0 = only inside the zone; 0.0 = no restriction. Only used with a mask. |
| region_hardness | FLOAT | 0.000–1 | (Regional) crispness of the zone edge. 0.0 = soft falloff; 1.0 = hard binary edge (tightest containment). Raise it if the reference bleeds outside the mask. Only used with a mask. |
| scheduleopt | FLOAT | Optional per-step curve in [0,1] (e.g. the FLOAT output of NKD Sigmas Curve) that MULTIPLIES the strength across denoise steps. Leave unconnected for a flat strength. | |
| maskopt | MASK | Optional zone to confine the reference to. Connect it to turn on regional control; leave it unconnected for a pure strength node. | |
| latentopt | LATENT | The canvas latent from Presampling — needed only when a mask is connected, to map it onto the token grid. Chain it from another Reference Control's latent output. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| model | MODEL | — |
| latent | LATENT | The latent passed through — chain into the next Reference Control to drive several references. |