Nodes/Krea2 Multi-LoRA Composer/Krea2 Multi-LoRA Composer
ComfyUI Node

Krea2 Multi-LoRA Composer

The Krea 2 node that stops two character LoRAs from melting into one face

By lokitsar·Created 2 months ago·Updated 2 months ago· 1
Krea2 Multi-LoRA Composer
  • model
  • clip
  • model
  • conditioning
  • prompt
  • mask_preview
  • diagnostics
  • latent
  • share_prompt_json
  • target_width
  • target_height
  • supersample_plan
scene_promptTwo people in the same scene, natural interaction, coherent lighting
width1024
height1024
regions_json[ { "name": "Character A", "enabled": true, "lora": "None", "trigger": "CHAR_A", "prompt": "", "strength": 1.0, "x": 0.05, "y": 0.08, "w": 0.4, "h": 0.84, "start": 0.0, "end": 1.0 }, { "name": "Character B", "enabled": true, "lora": "None", "trigger": "CHAR_B", "prompt": "", "strength": 1.0, "x": 0.55, "y": 0.08, "w": 0.4, "h": 0.84, "start": 0.0, "end": 1.0 } ]
feather0.08
overlap_policynearest
schedule_softness0.04
stricttrue
debugfalse
supersample_scale1.00
canvas_lora_json{ "enabled": false, "lora": "None", "trigger": "", "prompt": "", "strength": 1.0, "coverage": "unboxed", "start": 0.0, "end": 1.0 }

Two character LoRAs on Krea 2 in one image, and the model hands you a single person with a blended face. That smear is the single most complained-about thing in Krea 2 character work - the model routes either identity anywhere it likes, so both LoRAs fire on both figures and the characters collapse into an average. Krea2CharacterRouter (shown in ComfyUI as Krea2 Multi-LoRA Composer) is a purpose-built fix: one self-contained editor that assigns each character LoRA to a draggable region of the image, then makes the model respect the box.

It's part of the lokitsar/ComfyUI-Krea2-MultiLoRA-Composer pack and works only with Krea 2 (Raw or Turbo), its matching CLIP/VAE, and LoRAs trained for Krea 2. No API, no key, no extra Python packages - it's all local.

How it actually works

The node doesn't just stack LoRAs and hope. It routes each character adapter three ways at once, per the README:

  1. Adapter-delta routing - each LoRA's image-token contribution is masked to its assigned region, so a character LoRA contributes (nearly) zero outside its box.
  2. Token isolation - character text-fusion contributions apply to the matching subject phrase and are suppressed on competing phrases.
  3. Attention bias - each subject phrase is encouraged to attend to its own image region and away from the others.

The base model still does the global coherence - lighting, scene, interaction - and an optional Canvas LoRA covers the unboxed scenery or the whole image with a separate style. The project credits FreeFuse for the token-separation direction. The result is one Krea 2 generation, not a paste-up: the composed prompt is built for you and exposed as the prompt output.

The inputs that matter

The node ships a custom web UI (drag regions, search LoRAs, Set + reset), and everything you set there serializes into a couple of widgets. The ones you'll actually touch:

  • scene_prompt - shared scene language: camera, lighting, interaction. Keep character-specific stuff out of it; each character row's trigger and prompt describe only that character.
  • regions_json - the serialized rows (LoRA path, trigger, strength, box, schedule). Usually you edit this through the canvas UI, not by hand.
  • width / height - target canvas, 256–4096 in steps of 8.
  • supersample_scale - how big the internal render gets (see the SuperSampler article; 1.25 is the sweet spot for likeness).
  • feather (0.08 default) and overlap_policy (nearest) - how box edges blend and how overlapping regions divide. Leave them alone until you're chasing artifacts.
  • canvas_lora_json - optional environment/style LoRA. Disabled by default.
  • strict - on by default. It makes the node refuse to run when a routing check fails instead of silently degrading.

Outputs: model, conditioning, and latent feed the sampler; supersample_plan tells the sampler the target vs. working resolution; prompt shows the composed positive; mask_preview shows your regions; share_prompt_json is a portable scene export (import/paste from the UI).

Install

ComfyUI Manager (search "Krea2 Multi-LoRA Composer"), or:

cd ComfyUI/custom_nodes
git clone https://github.com/lokitsar/ComfyUI-Krea2-MultiLoRA-Composer

Restart ComfyUI and hard-refresh the browser. You still need Krea 2 itself: the Raw/Turbo checkpoint, the Krea 2 CLIP, and VAE (it uses the Qwen-Image VAE under the hood). With Turbo, the README's starting point is steps 8, CFG 1.0, euler/simple - and no negative-prompt instructions in your positive fields.

Where people get burned

  • Identity still bleeds if your triggers are vague or the LoRAs are weak. Enter the exact training trigger per character, keep boxes tight and separated, and start at strength 1.0.
  • Regions are 2D. A face on a poster behind your character occupies the same box and can inherit the identity - the README flags this outright.
  • strict mode errors when a trigger can't be aligned to Krea 2 tokens - usually means the trigger isn't in the prompt. Flip it off to get warnings instead, but you probably want to fix the prompt.
  • Canvas LoRA leakage - a strongly character-trained environment LoRA can still sneak its subject into the scene.

It's one of several tools attacking this exact problem (another is CliffNodes' Krea 2 bounding-box node), and the smear it targets is real community pain. Give it a shot with two tight boxes and a shared scene prompt - this is the closest thing to a set-and-forget multi-character Krea 2 workflow right now.

CategoryKrea2/Multi-LoRA Composer

Inputs (13)

NameTypeDefaultDescription
modelMODEL
clipCLIP
scene_promptSTRINGTwo people in the same scene, natural interaction, coherent lighting
widthINT1024256–4096
heightINT1024256–4096
regions_jsonSTRING[ { "name": "Character A", "enabled": true, "lora": "None", "trigger": "CHAR_A", "prompt": "", "strength": 1.0, "x": 0.05, "y": 0.08, "w": 0.4, "h": 0.84, "start": 0.0, "end": 1.0 }, { "name": "Character B", "enabled": true, "lora": "None", "trigger": "CHAR_B", "prompt": "", "strength": 1.0, "x": 0.55, "y": 0.08, "w": 0.4, "h": 0.84, "start": 0.0, "end": 1.0 } ]
featherFLOAT0.080–0.5
overlap_policyCOMBOnearest3 options: nearest, normalize, allow
schedule_softnessFLOAT0.040–0.25
strictBOOLEANtrue
debugBOOLEANfalse
supersample_scaleFLOAT1.001–2
canvas_lora_jsonSTRING{ "enabled": false, "lora": "None", "trigger": "", "prompt": "", "strength": 1.0, "coverage": "unboxed", "start": 0.0, "end": 1.0 }

Outputs (10)

NameTypeDescription
modelMODEL
conditioningCONDITIONING
promptSTRING
mask_previewIMAGE
diagnosticsSTRING
latentLATENT
share_prompt_jsonSTRING
target_widthINT
target_heightINT
supersample_planKREA2_SUPERSAMPLE_PLAN