@@ -442,6 +442,7 @@ class NewModelTextEncoderInvocation(BaseInvocation):
442442class NewModelDenoiseInvocation (BaseInvocation ):
443443 # Standard Fields
444444 latents: LatentsField | None = InputField(default = None )
445+ noise: LatentsField | None = InputField(default = None )
445446 positive_conditioning: ConditioningField = InputField()
446447 negative_conditioning: ConditioningField | None = InputField(default = None )
447448
@@ -453,6 +454,7 @@ class NewModelDenoiseInvocation(BaseInvocation):
453454 denoising_end: float = InputField(default = 1.0 , ge = 0 , le = 1 )
454455 steps: int = InputField(default = 20 , ge = 1 )
455456 cfg_scale: float = InputField(default = 7.0 )
457+ add_noise: bool = InputField(default = True )
456458
457459 # Image-to-Image / Inpainting
458460 denoise_mask: DenoiseMaskField | None = InputField(default = None )
@@ -461,16 +463,27 @@ class NewModelDenoiseInvocation(BaseInvocation):
461463 scheduler: Literal[" euler" , " heun" , " lcm" ] = InputField(default = " euler" )
462464
463465 def invoke (self , context : InvocationContext) -> LatentsOutput:
464- # 1. Generate noise
465- noise = get_noise_newmodel(seed, height, width, ... )
466-
467- # 2. Pack latents (if needed)
468- x = pack_newmodel(latents )
466+ # 1. Load or generate noise
467+ if self . noise is not None :
468+ noise = self ._load_and_validate_noise(context)
469+ else :
470+ noise = get_noise_newmodel(seed, height, width, ... )
469471
470- # 3 . Compute schedule
472+ # 2 . Compute schedule
471473 timesteps = get_schedule_newmodel(num_steps, denoising_start, denoising_end)
472474
473- # 4. Denoising loop
475+ # 3. Prepare init latents and img2img preblend
476+ if latents is not None and self .add_noise:
477+ x = noise * timesteps[0 ] + latents * (1.0 - timesteps[0 ])
478+ elif latents is not None :
479+ x = latents
480+ else :
481+ x = noise
482+
483+ # 4. Pack latents (if needed)
484+ x = pack_newmodel(x)
485+
486+ # 5. Denoising loop
474487 x = denoise(
475488 model = transformer,
476489 x = x,
@@ -480,12 +493,19 @@ class NewModelDenoiseInvocation(BaseInvocation):
480493 inpaint_extension = inpaint_extension, # For inpainting
481494 )
482495
483- # 5 . Unpack latents
496+ # 6 . Unpack latents
484497 latents = unpack_newmodel(x)
485498
486499 return LatentsOutput(latents = latents)
487500```
488501
502+ If the architecture supports external noise, the denoise invocation should
503+ accept an optional ` noise: LatentsField ` input and preserve the existing
504+ seed-driven path when it is not connected. Validate external noise against
505+ the architecture's expected rank, channel count, and spatial shape before
506+ using it. Existing workflows must continue to work unchanged when ` noise ` is
507+ left disconnected.
508+
489509### 4.4 VAE Encode Invocation
490510
491511** File:** ` invokeai/app/invocations/[newmodel]_vae_encode.py `
@@ -536,6 +556,9 @@ class NewModelVaeDecodeInvocation(BaseInvocation):
536556- [ ] Model loader invocation (` [newmodel]_model_loader.py ` )
537557- [ ] Text encoder invocation (` [newmodel]_text_encoder.py ` )
538558- [ ] Denoise invocation (` [newmodel]_denoise.py ` )
559+ - [ ] Add optional ` noise: LatentsField ` when the architecture supports
560+ external noise
561+ - [ ] Preserve the seed-driven fallback path when ` noise ` is not connected
539562- [ ] VAE encode invocation (` [newmodel]_vae_encode.py ` )
540563- [ ] VAE decode invocation (` [newmodel]_vae_decode.py ` )
541564- [ ] Define output classes (e.g., ` NewModelLoaderOutput ` )
@@ -574,6 +597,11 @@ def get_noise_newmodel(
574597 dtype = dtype,
575598 )
576599
600+ # If the architecture supports external noise, also extend
601+ # invokeai/app/invocations/universal_noise.py when the tensor contract can be
602+ # represented there. Only create a dedicated noise invocation when
603+ # Universal Noise cannot express the architecture cleanly.
604+
577605def pack_newmodel (x : torch.Tensor) -> torch.Tensor:
578606 """ Pack latents for transformer input.
579607
@@ -670,6 +698,13 @@ def denoise(
670698 return img
671699```
672700
701+ If the architecture supports external noise, the denoise path should accept
702+ validated external noise without changing the legacy seed-driven behavior.
703+ Review img2img and inpaint preblend logic carefully when adding scheduler
704+ support. If the initial latent/noise mix is computed before
705+ ` scheduler.set_timesteps() ` , confirm that the preblend matches the
706+ scheduler's true first effective sigma or timestep.
707+
673708### 5.3 Scheduler (if model-specific)
674709
675710** File:** ` invokeai/backend/[newmodel]/schedulers.py ` or use existing
@@ -690,11 +725,16 @@ NEWMODEL_SCHEDULER_MAP = {
690725### Backend Sampling and Denoise Checklist
691726
692727- [ ] Noise generation (` get_noise_newmodel() ` )
728+ - [ ] Extend ` invokeai/app/invocations/universal_noise.py ` when the
729+ architecture's noise tensor contract fits there
693730- [ ] Pack/unpack functions (if transformer-based)
694731- [ ] Schedule generation (` get_schedule_newmodel() ` )
695732- [ ] Position ID generation (if needed)
696733- [ ] Implement denoise loop
734+ - [ ] Validate external noise shape and rank if the architecture supports it
697735- [ ] Scheduler integration
736+ - [ ] Verify img2img and inpaint preblend parity with the scheduler's first
737+ effective timestep or sigma
698738- [ ] Inpaint extension integration
699739- [ ] Progress callbacks
700740
@@ -847,6 +887,11 @@ if (
847887}
848888```
849889
890+ If the architecture supports external noise, do not require generated
891+ workflows to connect it. Keep the denoise node backward compatible by
892+ leaving ` noise ` disconnected unless the workflow explicitly needs external
893+ noise.
894+
850895### Frontend Graph Building Checklist
851896
852897- [ ] Create graph builder (` buildNewModelGraph.ts ` )
@@ -1259,6 +1304,11 @@ For a **minimal txt2img integration**, the following files are required:
125913043. ` src/features/nodes/util/graph/generation/addInpaint.ts `
126013054. ` src/features/nodes/util/graph/generation/addOutpaint.ts `
12611306
1307+ If the architecture supports external noise , also extend
1308+ ` invokeai/app/invocations/universal_noise.py ` when possible and keep the
1309+ denoise invocation' s `noise` input optional so existing generated workflows
1310+ continue to work without modification.
1311+
12621312---
12631313
12641314## Reference: Existing Implementations
0 commit comments