diff --git a/__init__.py b/__init__.py index 5d7865c..1deab81 100644 --- a/__init__.py +++ b/__init__.py @@ -1,10 +1,12 @@ -from .nodes import SamplerInversedEulerNode +from .nodes import SamplerInversedEulerNode, MixNoiseNode NODE_CLASS_MAPPINGS = { "SamplerInversedEulerNode": SamplerInversedEulerNode, + "MixNoiseNode": MixNoiseNode, } NODE_DISPLAY_NAME_MAPPINGS = { "SamplerInversedEulerNode": "Inversed Euler Sampler", + "MixNoiseNode": "Mix Noise with Latent" } diff --git a/example_workflow/example_noise_inversion.json b/example_workflow/example_noise_inversion.json new file mode 100644 index 0000000..53b8d01 --- /dev/null +++ b/example_workflow/example_noise_inversion.json @@ -0,0 +1,1057 @@ +{ + "last_node_id": 39, + "last_link_id": 90, + "nodes": [ + { + "id": 11, + "type": "LoadImage", + "pos": [ + 649, + 779 + ], + "size": { + "0": 315, + "1": 314 + }, + "flags": {}, + "order": 0, + "mode": 0, + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 32 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "MASK", + "type": "MASK", + "links": null, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "cat.jpeg", + "image" + ] + }, + { + "id": 23, + "type": "ImageScale", + "pos": [ + 1076, + 927 + ], + "size": { + "0": 315, + "1": 130 + }, + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [ + { + "name": "image", + "type": "IMAGE", + "link": 32 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 33, + 75 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "ImageScale" + }, + "widgets_values": [ + "nearest-exact", + 512, + 512, + "disabled" + ] + }, + { + "id": 3, + "type": "CLIPTextEncode", + "pos": [ + 1273, + 128 + ], + "size": { + "0": 400, + "1": 200 + }, + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 2 + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 59 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "" + ] + }, + { + "id": 1, + "type": "CheckpointLoaderSimple", + "pos": [ + 567, + 318 + ], + "size": { + "0": 315, + "1": 98 + }, + "flags": {}, + "order": 1, + "mode": 0, + "outputs": [ + { + "name": "MODEL", + "type": "MODEL", + "links": [ + 7, + 61, + 66 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "CLIP", + "type": "CLIP", + "links": [ + 1, + 2, + 3 + ], + "shape": 3, + "slot_index": 1 + }, + { + "name": "VAE", + "type": "VAE", + "links": null, + "shape": 3, + "slot_index": 2 + } + ], + "properties": { + "Node name for S&R": "CheckpointLoaderSimple" + }, + "widgets_values": [ + "photon_v1.safetensors" + ] + }, + { + "id": 7, + "type": "VAELoader", + "pos": [ + 571, + 519 + ], + "size": { + "0": 315, + "1": 58 + }, + "flags": {}, + "order": 2, + "mode": 0, + "outputs": [ + { + "name": "VAE", + "type": "VAE", + "links": [ + 11, + 42, + 70 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "VAELoader" + }, + "widgets_values": [ + "vae-ft-mse-840000-ema-pruned.safetensors" + ] + }, + { + "id": 28, + "type": "PreviewImage", + "pos": [ + 3778, + 641 + ], + "size": { + "0": 692.9580688476562, + "1": 584.5953369140625 + }, + "flags": {}, + "order": 15, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 43 + } + ], + "properties": { + "Node name for S&R": "PreviewImage" + } + }, + { + "id": 12, + "type": "VAEEncode", + "pos": [ + 1731, + 740 + ], + "size": { + "0": 210, + "1": 46 + }, + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [ + { + "name": "pixels", + "type": "IMAGE", + "link": 33 + }, + { + "name": "vae", + "type": "VAE", + "link": 11 + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 68, + 72 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "VAEEncode" + } + }, + { + "id": 2, + "type": "CLIPTextEncode", + "pos": [ + 1264, + 401 + ], + "size": { + "0": 400, + "1": 200 + }, + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 1 + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 64, + 65 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "" + ] + }, + { + "id": 10, + "type": "BasicScheduler", + "pos": [ + 1374, + 784 + ], + "size": { + "0": 242.59632873535156, + "1": 106 + }, + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 7 + } + ], + "outputs": [ + { + "name": "SIGMAS", + "type": "SIGMAS", + "links": [ + 30 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "BasicScheduler" + }, + "widgets_values": [ + "ddim_uniform", + 50, + 1 + ] + }, + { + "id": 38, + "type": "PreviewImage", + "pos": [ + 3787, + 7 + ], + "size": { + "0": 692.9580688476562, + "1": 584.5953369140625 + }, + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 75 + } + ], + "properties": { + "Node name for S&R": "PreviewImage" + } + }, + { + "id": 37, + "type": "PreviewImage", + "pos": [ + 4500, + 4 + ], + "size": { + "0": 692.9580688476562, + "1": 584.5953369140625 + }, + "flags": {}, + "order": 19, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 71 + } + ], + "properties": { + "Node name for S&R": "PreviewImage" + } + }, + { + "id": 27, + "type": "VAEDecode", + "pos": [ + 3407, + 796 + ], + "size": { + "0": 210, + "1": 46 + }, + "flags": {}, + "order": 13, + "mode": 0, + "inputs": [ + { + "name": "samples", + "type": "LATENT", + "link": 86 + }, + { + "name": "vae", + "type": "VAE", + "link": 42 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 43 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "VAEDecode" + } + }, + { + "id": 26, + "type": "SamplerInversedEulerNode", + "pos": [ + 1708, + 1057 + ], + "size": { + "0": 210, + "1": 26 + }, + "flags": {}, + "order": 3, + "mode": 0, + "outputs": [ + { + "name": "SAMPLER", + "type": "SAMPLER", + "links": [ + 62 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "SamplerInversedEulerNode" + } + }, + { + "id": 22, + "type": "FlipSigmas", + "pos": [ + 1741, + 1196 + ], + "size": { + "0": 210, + "1": 26 + }, + "flags": {}, + "order": 11, + "mode": 0, + "inputs": [ + { + "name": "sigmas", + "type": "SIGMAS", + "link": 30 + } + ], + "outputs": [ + { + "name": "SIGMAS", + "type": "SIGMAS", + "links": [ + 81 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "FlipSigmas" + } + }, + { + "id": 36, + "type": "VAEDecode", + "pos": [ + 3438, + -130 + ], + "size": { + "0": 210, + "1": 46 + }, + "flags": {}, + "order": 18, + "mode": 0, + "inputs": [ + { + "name": "samples", + "type": "LATENT", + "link": 69 + }, + { + "name": "vae", + "type": "VAE", + "link": 70 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 71 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "VAEDecode" + } + }, + { + "id": 34, + "type": "KSamplerAdvanced", + "pos": [ + 3071, + 337 + ], + "size": { + "0": 315, + "1": 334 + }, + "flags": {}, + "order": 17, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 61 + }, + { + "name": "positive", + "type": "CONDITIONING", + "link": 58 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 59 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 90 + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 69 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "KSamplerAdvanced" + }, + "widgets_values": [ + "disable", + 1, + "fixed", + 20, + 8, + "dpmpp_2m", + "karras", + 0, + 10000, + "disable" + ] + }, + { + "id": 35, + "type": "SamplerCustom", + "pos": [ + 2103, + 974 + ], + "size": { + "0": 293.5057067871094, + "1": 230 + }, + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "MODEL", + "link": 66 + }, + { + "name": "positive", + "type": "CONDITIONING", + "link": 64 + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": 65 + }, + { + "name": "sampler", + "type": "SAMPLER", + "link": 62, + "slot_index": 3 + }, + { + "name": "sigmas", + "type": "SIGMAS", + "link": 81, + "slot_index": 4 + }, + { + "name": "latent_image", + "type": "LATENT", + "link": 72 + } + ], + "outputs": [ + { + "name": "output", + "type": "LATENT", + "links": [ + 86, + 88 + ], + "shape": 3, + "slot_index": 0 + }, + { + "name": "denoised_output", + "type": "LATENT", + "links": [], + "shape": 3, + "slot_index": 1 + } + ], + "properties": { + "Node name for S&R": "SamplerCustom" + }, + "widgets_values": [ + true, + 764392635480520, + "fixed", + 1 + ] + }, + { + "id": 4, + "type": "CLIPTextEncode", + "pos": [ + 1277, + -127 + ], + "size": { + "0": 400, + "1": 200 + }, + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "name": "clip", + "type": "CLIP", + "link": 3 + } + ], + "outputs": [ + { + "name": "CONDITIONING", + "type": "CONDITIONING", + "links": [ + 58 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "widgets_values": [ + "a cat" + ] + }, + { + "id": 33, + "type": "InjectNoiseToLatent", + "pos": [ + 2754, + 714 + ], + "size": [ + 210, + 146 + ], + "flags": {}, + "order": 16, + "mode": 0, + "inputs": [ + { + "name": "latents", + "type": "LATENT", + "link": 68 + }, + { + "name": "noise", + "type": "LATENT", + "link": 83 + }, + { + "name": "mask", + "type": "MASK", + "link": null + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 90 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "InjectNoiseToLatent" + }, + "widgets_values": [ + 1, + false, + false + ] + }, + { + "id": 39, + "type": "MixNoiseNode", + "pos": [ + 2479, + 831 + ], + "size": [ + 210, + 58 + ], + "flags": {}, + "order": 14, + "mode": 0, + "inputs": [ + { + "name": "latent", + "type": "LATENT", + "link": 88 + } + ], + "outputs": [ + { + "name": "LATENT", + "type": "LATENT", + "links": [ + 83 + ], + "shape": 3, + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "MixNoiseNode" + }, + "widgets_values": [ + 0.1 + ] + } + ], + "links": [ + [ + 1, + 1, + 1, + 2, + 0, + "CLIP" + ], + [ + 2, + 1, + 1, + 3, + 0, + "CLIP" + ], + [ + 3, + 1, + 1, + 4, + 0, + "CLIP" + ], + [ + 7, + 1, + 0, + 10, + 0, + "MODEL" + ], + [ + 11, + 7, + 0, + 12, + 1, + "VAE" + ], + [ + 30, + 10, + 0, + 22, + 0, + "SIGMAS" + ], + [ + 32, + 11, + 0, + 23, + 0, + "IMAGE" + ], + [ + 33, + 23, + 0, + 12, + 0, + "IMAGE" + ], + [ + 42, + 7, + 0, + 27, + 1, + "VAE" + ], + [ + 43, + 27, + 0, + 28, + 0, + "IMAGE" + ], + [ + 58, + 4, + 0, + 34, + 1, + "CONDITIONING" + ], + [ + 59, + 3, + 0, + 34, + 2, + "CONDITIONING" + ], + [ + 61, + 1, + 0, + 34, + 0, + "MODEL" + ], + [ + 62, + 26, + 0, + 35, + 3, + "SAMPLER" + ], + [ + 64, + 2, + 0, + 35, + 1, + "CONDITIONING" + ], + [ + 65, + 2, + 0, + 35, + 2, + "CONDITIONING" + ], + [ + 66, + 1, + 0, + 35, + 0, + "MODEL" + ], + [ + 68, + 12, + 0, + 33, + 0, + "LATENT" + ], + [ + 69, + 34, + 0, + 36, + 0, + "LATENT" + ], + [ + 70, + 7, + 0, + 36, + 1, + "VAE" + ], + [ + 71, + 36, + 0, + 37, + 0, + "IMAGE" + ], + [ + 72, + 12, + 0, + 35, + 5, + "LATENT" + ], + [ + 75, + 23, + 0, + 38, + 0, + "IMAGE" + ], + [ + 81, + 22, + 0, + 35, + 4, + "SIGMAS" + ], + [ + 83, + 39, + 0, + 33, + 1, + "LATENT" + ], + [ + 86, + 35, + 0, + 27, + 0, + "LATENT" + ], + [ + 88, + 35, + 0, + 39, + 0, + "LATENT" + ], + [ + 90, + 33, + 0, + 34, + 3, + "LATENT" + ] + ], + "groups": [], + "config": {}, + "extra": {}, + "version": 0.4 +} \ No newline at end of file diff --git a/nodes.py b/nodes.py index 80b90e8..73d1be6 100644 --- a/nodes.py +++ b/nodes.py @@ -44,3 +44,28 @@ class SamplerInversedEulerNode: ksampler = KSAMPLER(sample_inversed_euler) return (ksampler, ) + +# combined_noise = ((1 - randomness) * rec_noise + randomness * rand_noise) / ((randomness**2 + (1-randomness)**2) ** 0.5) + + +class MixNoiseNode: + @classmethod + def INPUT_TYPES(s): + return {"required": { + "latent": ("LATENT", ), + "randomness": ("FLOAT", {"default": 0.1, "min": 0.0, "max": 1.0, "step": 0.01, "round": False}), + }} + + RETURN_TYPES = ("LATENT",) + CATEGORY = "sampling/custom_sampling/samplers" + + FUNCTION = "combine" + + def combine(self, latent, randomness): + latent_image = latent['samples'] + rand_noise = torch.randn_like(latent_image) + combined_noise = ((1 - randomness) * latent_image + randomness * + rand_noise) / ((randomness**2 + (1-randomness)**2) ** 0.5) + latent = latent.copy() + latent['samples'] = combined_noise + return (latent, )