New additive node for identity-preserving edits: the clean VAE-encoded
source rides the sequence as a frame≠0 reference token block while a
fresh-noise target is denoised, and only the target is decoded — the
appearance path from lbouaraba/comfyui-krea2edit, mapped onto our engine
(sequence [text | src(frame=1) | target(frame=0)], mirroring the 3-axis
RoPE frame scheme that was already present but unused).
Engine additions are isolated: transformer gains prepare_edit +
denoise_step_edit, sampling gains sample_edit + build_edit_positions,
pipeline gains generate_edit; the txt2img/img2img sample() path is
untouched (verified txt2img stays pixel-identical to the parity ref).
Pairs with the krea2_edit identity LoRA (conradlocke/krea2-identity-edit),
which loads through the existing Krea2LoRA node unchanged (ai-toolkit
reference naming, 28 blocks, 0 unmatched keys). Validated: source fox +
"red scarf" keeps the fox's identity while applying the edit; the LoRA
sharpens edit coherence markedly (see tools/test_edit.py). Second
reference image supported for multi-ref edit LoRAs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New additive node (existing four untouched): VAE-encodes a source image
and denoises from a noised version of it. Rectified-flow interpolant
x_t=(1-t)·z0+t·noise, entering the schedule at t=denoise; denoise=1.0
takes the exact txt2img code path (verified pixel-identical to the
parity reference — the hard guard that generation is undisturbed).
Engine changes are additive: sample() gains init_latent/strength
(strength>=1.0 is a byte-identical no-op), pipeline gains
generate_img2img() reusing the prompt cache + LoRA path, nodes.py gains
_from_image_tensor. VAE encode input range verified [-1,1] (round-trip
45 dB). Denoise sweep 0.3→0.9 is monotonic and coherent; contact sheet
and strength=1.0 guard in tools/test_img2img.py.
First rung of the image-conditioning ladder (img2img → in-context edit
→ grounded vision); reuses the VAE-encode plumbing the edit path needs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Prompts are padded to 512 text tokens; ~470 of them are dead padding that
previously rode through all 28 attention blocks on every denoising step
and forced a dense (B,1,L,L) additive mask. Gather the union of valid
columns instead (layout is [prompt, padding, suffix], so this is a gather,
not a slice); single-prompt batches then run fully mask-free.
Mathematically exact (f32 check: velocity diff collapses to ~3e-5,
1-cos = 0.0), but the shorter sequence tiles bf16 kernels differently, so
fixed seeds render equal-quality, non-bit-identical images vs 0.3.x —
side-by-side reviewed and accepted. KREA2_EXACT_LEGACY=1 restores the
padded path for pre-upgrade seed reproducibility.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Split SingleStreamDiT.__call__ into prepare_conditioning() (text fusion,
RoPE tables, attention masks — identical every step) and denoise_step();
sample() now prepares once and steps 8 times instead of recomputing the
whole text path per step. Also eliminates the two .item() GPU syncs that
_additive_mask forced on every step. __call__ still composes both, so the
external API is unchanged. Parity: bit-exact incl. LoRA case.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Krea2ModelLoader / Krea2LoRA / Krea2Generate / Krea2Unload nodes running
Krea-2-Turbo on Apple MLX in-process, returning ComfyUI IMAGE tensors.
The krea2_engine/ pipeline is vendored directly in this repo (no external
git dependency) — see NOTICE for the full attribution chain back to the
original Krea 2 model and the MLX port it builds on.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>