Make regular empty latent node work properly on flux 2 variants. (#12050)

This commit is contained in:
comfyanonymous 2026-01-23 16:50:48 -08:00 committed by GitHub
parent e89b22993a
commit 9cf299a9f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 20 additions and 8 deletions

View File

@ -8,6 +8,7 @@ class LatentFormat:
latent_rgb_factors_bias = None latent_rgb_factors_bias = None
latent_rgb_factors_reshape = None latent_rgb_factors_reshape = None
taesd_decoder_name = None taesd_decoder_name = None
spacial_downscale_ratio = 8
def process_in(self, latent): def process_in(self, latent):
return latent * self.scale_factor return latent * self.scale_factor
@ -181,6 +182,7 @@ class Flux(SD3):
class Flux2(LatentFormat): class Flux2(LatentFormat):
latent_channels = 128 latent_channels = 128
spacial_downscale_ratio = 16
def __init__(self): def __init__(self):
self.latent_rgb_factors =[ self.latent_rgb_factors =[
@ -749,6 +751,7 @@ class ACEAudio(LatentFormat):
class ChromaRadiance(LatentFormat): class ChromaRadiance(LatentFormat):
latent_channels = 3 latent_channels = 3
spacial_downscale_ratio = 1
def __init__(self): def __init__(self):
self.latent_rgb_factors = [ self.latent_rgb_factors = [

View File

@ -37,12 +37,18 @@ def prepare_noise(latent_image, seed, noise_inds=None):
return noises return noises
def fix_empty_latent_channels(model, latent_image): def fix_empty_latent_channels(model, latent_image, downscale_ratio_spacial=None):
if latent_image.is_nested: if latent_image.is_nested:
return latent_image return latent_image
latent_format = model.get_model_object("latent_format") #Resize the empty latent image so it has the right number of channels latent_format = model.get_model_object("latent_format") #Resize the empty latent image so it has the right number of channels
if latent_format.latent_channels != latent_image.shape[1] and torch.count_nonzero(latent_image) == 0: if torch.count_nonzero(latent_image) == 0:
latent_image = comfy.utils.repeat_to_batch_size(latent_image, latent_format.latent_channels, dim=1) if latent_format.latent_channels != latent_image.shape[1]:
latent_image = comfy.utils.repeat_to_batch_size(latent_image, latent_format.latent_channels, dim=1)
if downscale_ratio_spacial is not None:
if downscale_ratio_spacial != latent_format.spacial_downscale_ratio:
ratio = downscale_ratio_spacial / latent_format.spacial_downscale_ratio
latent_image = comfy.utils.common_upscale(latent_image, round(latent_image.shape[-1] * ratio), round(latent_image.shape[-2] * ratio), "nearest-exact", crop="disabled")
if latent_format.latent_dimensions == 3 and latent_image.ndim == 4: if latent_format.latent_dimensions == 3 and latent_image.ndim == 4:
latent_image = latent_image.unsqueeze(2) latent_image = latent_image.unsqueeze(2)
return latent_image return latent_image

View File

@ -741,7 +741,7 @@ class SamplerCustom(io.ComfyNode):
latent = latent_image latent = latent_image
latent_image = latent["samples"] latent_image = latent["samples"]
latent = latent.copy() latent = latent.copy()
latent_image = comfy.sample.fix_empty_latent_channels(model, latent_image) latent_image = comfy.sample.fix_empty_latent_channels(model, latent_image, latent.get("downscale_ratio_spacial", None))
latent["samples"] = latent_image latent["samples"] = latent_image
if not add_noise: if not add_noise:
@ -760,6 +760,7 @@ class SamplerCustom(io.ComfyNode):
samples = comfy.sample.sample_custom(model, noise, cfg, sampler, sigmas, positive, negative, latent_image, noise_mask=noise_mask, callback=callback, disable_pbar=disable_pbar, seed=noise_seed) samples = comfy.sample.sample_custom(model, noise, cfg, sampler, sigmas, positive, negative, latent_image, noise_mask=noise_mask, callback=callback, disable_pbar=disable_pbar, seed=noise_seed)
out = latent.copy() out = latent.copy()
out.pop("downscale_ratio_spacial", None)
out["samples"] = samples out["samples"] = samples
if "x0" in x0_output: if "x0" in x0_output:
x0_out = model.model.process_latent_out(x0_output["x0"].cpu()) x0_out = model.model.process_latent_out(x0_output["x0"].cpu())
@ -939,7 +940,7 @@ class SamplerCustomAdvanced(io.ComfyNode):
latent = latent_image latent = latent_image
latent_image = latent["samples"] latent_image = latent["samples"]
latent = latent.copy() latent = latent.copy()
latent_image = comfy.sample.fix_empty_latent_channels(guider.model_patcher, latent_image) latent_image = comfy.sample.fix_empty_latent_channels(guider.model_patcher, latent_image, latent.get("downscale_ratio_spacial", None))
latent["samples"] = latent_image latent["samples"] = latent_image
noise_mask = None noise_mask = None
@ -954,6 +955,7 @@ class SamplerCustomAdvanced(io.ComfyNode):
samples = samples.to(comfy.model_management.intermediate_device()) samples = samples.to(comfy.model_management.intermediate_device())
out = latent.copy() out = latent.copy()
out.pop("downscale_ratio_spacial", None)
out["samples"] = samples out["samples"] = samples
if "x0" in x0_output: if "x0" in x0_output:
x0_out = guider.model_patcher.model.process_latent_out(x0_output["x0"].cpu()) x0_out = guider.model_patcher.model.process_latent_out(x0_output["x0"].cpu())

View File

@ -55,7 +55,7 @@ class EmptySD3LatentImage(io.ComfyNode):
@classmethod @classmethod
def execute(cls, width, height, batch_size=1) -> io.NodeOutput: def execute(cls, width, height, batch_size=1) -> io.NodeOutput:
latent = torch.zeros([batch_size, 16, height // 8, width // 8], device=comfy.model_management.intermediate_device()) latent = torch.zeros([batch_size, 16, height // 8, width // 8], device=comfy.model_management.intermediate_device())
return io.NodeOutput({"samples":latent}) return io.NodeOutput({"samples": latent, "downscale_ratio_spacial": 8})
generate = execute # TODO: remove generate = execute # TODO: remove

View File

@ -1230,7 +1230,7 @@ class EmptyLatentImage:
def generate(self, width, height, batch_size=1): def generate(self, width, height, batch_size=1):
latent = torch.zeros([batch_size, 4, height // 8, width // 8], device=self.device) latent = torch.zeros([batch_size, 4, height // 8, width // 8], device=self.device)
return ({"samples":latent}, ) return ({"samples": latent, "downscale_ratio_spacial": 8}, )
class LatentFromBatch: class LatentFromBatch:
@ -1538,7 +1538,7 @@ class SetLatentNoiseMask:
def common_ksampler(model, seed, steps, cfg, sampler_name, scheduler, positive, negative, latent, denoise=1.0, disable_noise=False, start_step=None, last_step=None, force_full_denoise=False): def common_ksampler(model, seed, steps, cfg, sampler_name, scheduler, positive, negative, latent, denoise=1.0, disable_noise=False, start_step=None, last_step=None, force_full_denoise=False):
latent_image = latent["samples"] latent_image = latent["samples"]
latent_image = comfy.sample.fix_empty_latent_channels(model, latent_image) latent_image = comfy.sample.fix_empty_latent_channels(model, latent_image, latent.get("downscale_ratio_spacial", None))
if disable_noise: if disable_noise:
noise = torch.zeros(latent_image.size(), dtype=latent_image.dtype, layout=latent_image.layout, device="cpu") noise = torch.zeros(latent_image.size(), dtype=latent_image.dtype, layout=latent_image.layout, device="cpu")
@ -1556,6 +1556,7 @@ def common_ksampler(model, seed, steps, cfg, sampler_name, scheduler, positive,
denoise=denoise, disable_noise=disable_noise, start_step=start_step, last_step=last_step, denoise=denoise, disable_noise=disable_noise, start_step=start_step, last_step=last_step,
force_full_denoise=force_full_denoise, noise_mask=noise_mask, callback=callback, disable_pbar=disable_pbar, seed=seed) force_full_denoise=force_full_denoise, noise_mask=noise_mask, callback=callback, disable_pbar=disable_pbar, seed=seed)
out = latent.copy() out = latent.copy()
out.pop("downscale_ratio_spacial", None)
out["samples"] = samples out["samples"] = samples
return (out, ) return (out, )