From e7a21dbf0b8ad0dd9a192f769831f3c1d19af7dd Mon Sep 17 00:00:00 2001 From: Artiprocher Date: Thu, 19 Jun 2025 14:53:11 +0800 Subject: [PATCH 01/14] flux-refactor --- diffsynth/flux/FLUX.1-dev.py | 23 ++ diffsynth/pipelines/flux_image_new.py | 510 ++++++++++++++++++++++++++ diffsynth/pipelines/wan_video_new.py | 30 +- 3 files changed, 561 insertions(+), 2 deletions(-) create mode 100644 diffsynth/flux/FLUX.1-dev.py create mode 100644 diffsynth/pipelines/flux_image_new.py diff --git a/diffsynth/flux/FLUX.1-dev.py b/diffsynth/flux/FLUX.1-dev.py new file mode 100644 index 0000000..6355436 --- /dev/null +++ b/diffsynth/flux/FLUX.1-dev.py @@ -0,0 +1,23 @@ +import torch +from PIL import Image +from diffsynth import save_video, VideoData +from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig +from modelscope import dataset_snapshot_download + + +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), + ], +) + +image = pipe( + prompt="a girl", + seed=0, +) +image.save("0.jpg") \ No newline at end of file diff --git a/diffsynth/pipelines/flux_image_new.py b/diffsynth/pipelines/flux_image_new.py new file mode 100644 index 0000000..bab84b8 --- /dev/null +++ b/diffsynth/pipelines/flux_image_new.py @@ -0,0 +1,510 @@ +import torch, warnings, glob, os, types +import numpy as np +from PIL import Image +from einops import repeat, reduce +from typing import Optional, Union +from dataclasses import dataclass +from modelscope import snapshot_download +from einops import rearrange +import numpy as np +from PIL import Image +from tqdm import tqdm +from typing import Optional +from typing_extensions import Literal + +from ..schedulers import FlowMatchScheduler +from ..prompters import FluxPrompter +from ..models import ModelManager, SD3TextEncoder1, FluxTextEncoder2, FluxDiT, FluxVAEEncoder, FluxVAEDecoder +from ..models.tiler import FastTileWorker +from .wan_video_new import BasePipeline, ModelConfig, PipelineUnitRunner, PipelineUnit + + + +class FluxImagePipeline(BasePipeline): + + def __init__(self, device="cuda", torch_dtype=torch.bfloat16): + super().__init__( + device=device, torch_dtype=torch_dtype, + height_division_factor=16, width_division_factor=16, + ) + self.scheduler = FlowMatchScheduler() + self.prompter = FluxPrompter() + self.text_encoder_1: SD3TextEncoder1 = None + self.text_encoder_2: FluxTextEncoder2 = None + self.dit: FluxDiT = None + self.vae_decoder: FluxVAEDecoder = None + self.vae_encoder: FluxVAEEncoder = None + self.unit_runner = PipelineUnitRunner() + self.in_iteration_models = ("dit", ) + self.units = [ + FluxImageUnit_ShapeChecker(), + FluxImageUnit_NoiseInitializer(), + FluxImageUnit_PromptEmbedder(), + FluxImageUnit_InputImageEmbedder(), + FluxImageUnit_ImageIDs(), + FluxImageUnit_EmbeddedGuidanceEmbedder(), + ] + self.model_fn = model_fn_flux_image + + + def load_lora(self, module, path, alpha=1): + pass + + + def training_loss(self, **inputs): + timestep_id = torch.randint(0, self.scheduler.num_train_timesteps, (1,)) + timestep = self.scheduler.timesteps[timestep_id].to(dtype=self.torch_dtype, device=self.device) + + inputs["latents"] = self.scheduler.add_noise(inputs["input_latents"], inputs["noise"], timestep) + training_target = self.scheduler.training_target(inputs["input_latents"], inputs["noise"], timestep) + + noise_pred = self.model_fn(**inputs, timestep=timestep) + + loss = torch.nn.functional.mse_loss(noise_pred.float(), training_target.float()) + loss = loss * self.scheduler.training_weight(timestep) + return loss + + + def enable_vram_management(self, num_persistent_param_in_dit=None, vram_limit=None, vram_buffer=0.5): + pass + + + @staticmethod + def from_pretrained( + torch_dtype: torch.dtype = torch.bfloat16, + device: Union[str, torch.device] = "cuda", + model_configs: list[ModelConfig] = [], + tokenizer_config: ModelConfig = ModelConfig(model_id="Wan-AI/Wan2.1-T2V-1.3B", origin_file_pattern="google/*"), + local_model_path: str = "./models", + skip_download: bool = False, + redirect_common_files: bool = True, + use_usp=False, + ): + # Download and load models + model_manager = ModelManager() + for model_config in model_configs: + model_config.download_if_necessary(local_model_path, skip_download=skip_download) + model_manager.load_model( + model_config.path, + device=model_config.offload_device or device, + torch_dtype=model_config.offload_dtype or torch_dtype + ) + + # Initialize pipeline + pipe = FluxImagePipeline(device=device, torch_dtype=torch_dtype) + pipe.text_encoder_1 = model_manager.fetch_model("sd3_text_encoder_1") + pipe.text_encoder_2 = model_manager.fetch_model("flux_text_encoder_2") + pipe.dit = model_manager.fetch_model("flux_dit") + pipe.vae_decoder = model_manager.fetch_model("flux_vae_decoder") + pipe.vae_encoder = model_manager.fetch_model("flux_vae_encoder") + pipe.prompter.fetch_models(pipe.text_encoder_1, pipe.text_encoder_2) + + return pipe + + + @torch.no_grad() + def __call__( + self, + # Prompt + prompt, + negative_prompt="", + cfg_scale=1.0, + embedded_guidance=3.5, + t5_sequence_length=512, + # Image + input_image=None, + denoising_strength=1.0, + # Shape + height=1024, + width=1024, + # Randomness + seed=None, + rand_device: Optional[str] = "cpu", + # Scheduler + sigma_shift=None, + # Steps + num_inference_steps=30, + # local prompts + multidiffusion_prompts=(), + multidiffusion_masks=(), + multidiffusion_scales=(), + # ControlNet + controlnet_inputs=None, + # IP-Adapter + ipadapter_images=None, + ipadapter_scale=1.0, + # EliGen + eligen_entity_prompts=None, + eligen_entity_masks=None, + eligen_enable_on_negative=False, + eligen_enable_inpaint=False, + # InfiniteYou + infinityou_id_image=None, + infinityou_guidance=1.0, + # Flex + flex_inpaint_image=None, + flex_inpaint_mask=None, + flex_control_image=None, + flex_control_strength=0.5, + flex_control_stop=0.5, + # Step1x + step1x_reference_image=None, + # TeaCache + tea_cache_l1_thresh=None, + # Tile + tiled=False, + tile_size=128, + tile_stride=64, + # Progress bar + progress_bar_cmd=tqdm, + ): + # Scheduler + self.scheduler.set_timesteps(num_inference_steps, denoising_strength=denoising_strength, shift=sigma_shift) + + inputs_posi = { + "prompt": prompt, + } + inputs_nega = { + "negative_prompt": negative_prompt, + } + inputs_shared = { + "cfg_scale": cfg_scale, "embedded_guidance": embedded_guidance, "t5_sequence_length": t5_sequence_length, + "input_image": input_image, "denoising_strength": denoising_strength, + "height": height, "width": width, + "seed": seed, "rand_device": rand_device, + "sigma_shift": sigma_shift, "num_inference_steps": num_inference_steps, + "multidiffusion_prompts": multidiffusion_prompts, "multidiffusion_masks": multidiffusion_masks, "multidiffusion_scales": multidiffusion_scales, + "controlnet_inputs": controlnet_inputs, + "ipadapter_images": ipadapter_images, "ipadapter_scale": ipadapter_scale, + "eligen_entity_prompts": eligen_entity_prompts, "eligen_entity_masks": eligen_entity_masks, "eligen_enable_on_negative": eligen_enable_on_negative, "eligen_enable_inpaint": eligen_enable_inpaint, + "infinityou_id_image": infinityou_id_image, "infinityou_guidance": infinityou_guidance, + "flex_inpaint_image": flex_inpaint_image, "flex_inpaint_mask": flex_inpaint_mask, "flex_control_image": flex_control_image, "flex_control_strength": flex_control_strength, "flex_control_stop": flex_control_stop, + "step1x_reference_image": step1x_reference_image, + "tea_cache_l1_thresh": tea_cache_l1_thresh, + "tiled": tiled, "tile_size": tile_size, "tile_stride": tile_stride, + "progress_bar_cmd": progress_bar_cmd, + } + for unit in self.units: + inputs_shared, inputs_posi, inputs_nega = self.unit_runner(unit, self, inputs_shared, inputs_posi, inputs_nega) + + # Denoise + self.load_models_to_device(self.in_iteration_models) + models = {name: getattr(self, name) for name in self.in_iteration_models} + for progress_id, timestep in enumerate(progress_bar_cmd(self.scheduler.timesteps)): + timestep = timestep.unsqueeze(0).to(dtype=self.torch_dtype, device=self.device) + + # Inference + noise_pred_posi = self.model_fn(**models, **inputs_shared, **inputs_posi, timestep=timestep) + if cfg_scale != 1.0: + noise_pred_nega = self.model_fn(**models, **inputs_shared, **inputs_nega, timestep=timestep) + noise_pred = noise_pred_nega + cfg_scale * (noise_pred_posi - noise_pred_nega) + else: + noise_pred = noise_pred_posi + + # Scheduler + inputs_shared["latents"] = self.scheduler.step(noise_pred, self.scheduler.timesteps[progress_id], inputs_shared["latents"]) + + # Decode + self.load_models_to_device(['vae_decoder']) + image = self.vae_decoder(inputs_shared["latents"], device=self.device, tiled=tiled, tile_size=tile_size, tile_stride=tile_stride) + image = self.vae_output_to_image(image) + self.load_models_to_device([]) + + return image + + + +class FluxImageUnit_ShapeChecker(PipelineUnit): + def __init__(self): + super().__init__(input_params=("height", "width")) + + def process(self, pipe: FluxImagePipeline, height, width): + height, width = pipe.check_resize_height_width(height, width) + return {"height": height, "width": width} + + + +class FluxImageUnit_NoiseInitializer(PipelineUnit): + def __init__(self): + super().__init__(input_params=("height", "width", "seed", "rand_device")) + + def process(self, pipe: FluxImagePipeline, height, width, seed, rand_device): + noise = pipe.generate_noise((1, 16, height//8, width//8), seed=seed, rand_device=rand_device) + return {"noise": noise} + + + +class FluxImageUnit_InputImageEmbedder(PipelineUnit): + def __init__(self): + super().__init__( + input_params=("input_image", "noise", "tiled", "tile_size", "tile_stride"), + onload_model_names=("vae_encoder",) + ) + + def process(self, pipe: FluxImagePipeline, input_image, noise, tiled, tile_size, tile_stride): + if input_image is None: + return {"latents": noise, "input_latents": None} + pipe.load_models_to_device(['vae_encoder']) + image = pipe.preprocess_image(input_image).to(device=pipe.device, dtype=pipe.torch_dtype) + input_latents = pipe.vae_encoder(image, tiled=tiled, tile_size=tile_size, tile_stride=tile_stride) + if pipe.scheduler.training: + return {"latents": noise, "input_latents": input_latents} + else: + latents = pipe.scheduler.add_noise(input_latents, noise, timestep=pipe.scheduler.timesteps[0]) + return {"latents": latents, "input_latents": None} + + + +class FluxImageUnit_PromptEmbedder(PipelineUnit): + def __init__(self): + super().__init__( + seperate_cfg=True, + input_params_posi={"prompt": "prompt", "positive": "positive"}, + input_params_nega={"prompt": "negative_prompt", "positive": "positive"}, + input_params=("t5_sequence_length",), + onload_model_names=("text_encoder_1", "text_encoder_2") + ) + + def process(self, pipe: FluxImagePipeline, prompt, t5_sequence_length, positive) -> dict: + if pipe.text_encoder_1 is not None and pipe.text_encoder_2 is not None: + prompt_emb, pooled_prompt_emb, text_ids = pipe.prompter.encode_prompt( + prompt, device=pipe.device, positive=positive, t5_sequence_length=t5_sequence_length + ) + return {"prompt_emb": prompt_emb, "pooled_prompt_emb": pooled_prompt_emb, "text_ids": text_ids} + else: + return {} + + +class FluxImageUnit_ImageIDs(PipelineUnit): + def __init__(self): + super().__init__(input_params=("latents",)) + + def process(self, pipe: FluxImagePipeline, latents): + latent_image_ids = pipe.dit.prepare_image_ids(latents) + return {"image_ids": latent_image_ids} + + + +class FluxImageUnit_EmbeddedGuidanceEmbedder(PipelineUnit): + def __init__(self): + super().__init__(input_params=("embedded_guidance", "latents")) + + def process(self, pipe: FluxImagePipeline, embedded_guidance, latents): + guidance = torch.Tensor([embedded_guidance] * latents.shape[0]).to(device=latents.device, dtype=latents.dtype) + return {"guidance": guidance} + + + +class TeaCache: + def __init__(self, num_inference_steps, rel_l1_thresh): + self.num_inference_steps = num_inference_steps + self.step = 0 + self.accumulated_rel_l1_distance = 0 + self.previous_modulated_input = None + self.rel_l1_thresh = rel_l1_thresh + self.previous_residual = None + self.previous_hidden_states = None + + def check(self, dit: FluxDiT, hidden_states, conditioning): + inp = hidden_states.clone() + temb_ = conditioning.clone() + modulated_inp, _, _, _, _ = dit.blocks[0].norm1_a(inp, emb=temb_) + if self.step == 0 or self.step == self.num_inference_steps - 1: + should_calc = True + self.accumulated_rel_l1_distance = 0 + else: + coefficients = [4.98651651e+02, -2.83781631e+02, 5.58554382e+01, -3.82021401e+00, 2.64230861e-01] + rescale_func = np.poly1d(coefficients) + self.accumulated_rel_l1_distance += rescale_func(((modulated_inp-self.previous_modulated_input).abs().mean() / self.previous_modulated_input.abs().mean()).cpu().item()) + if self.accumulated_rel_l1_distance < self.rel_l1_thresh: + should_calc = False + else: + should_calc = True + self.accumulated_rel_l1_distance = 0 + self.previous_modulated_input = modulated_inp + self.step += 1 + if self.step == self.num_inference_steps: + self.step = 0 + if should_calc: + self.previous_hidden_states = hidden_states.clone() + return not should_calc + + def store(self, hidden_states): + self.previous_residual = hidden_states - self.previous_hidden_states + self.previous_hidden_states = None + + def update(self, hidden_states): + hidden_states = hidden_states + self.previous_residual + return hidden_states + + +def model_fn_flux_image( + dit: FluxDiT, + controlnet=None, + step1x_connector=None, + latents=None, + timestep=None, + prompt_emb=None, + pooled_prompt_emb=None, + guidance=None, + text_ids=None, + image_ids=None, + controlnet_frames=None, + tiled=False, + tile_size=128, + tile_stride=64, + entity_prompt_emb=None, + entity_masks=None, + ipadapter_kwargs_list={}, + id_emb=None, + infinityou_guidance=None, + flex_condition=None, + flex_uncondition=None, + flex_control_stop_timestep=None, + step1x_llm_embedding=None, + step1x_mask=None, + step1x_reference_latents=None, + tea_cache: TeaCache = None, + **kwargs +): + if tiled: + def flux_forward_fn(hl, hr, wl, wr): + tiled_controlnet_frames = [f[:, :, hl: hr, wl: wr] for f in controlnet_frames] if controlnet_frames is not None else None + return model_fn_flux_image( + dit=dit, + controlnet=controlnet, + latents=latents[:, :, hl: hr, wl: wr], + timestep=timestep, + prompt_emb=prompt_emb, + pooled_prompt_emb=pooled_prompt_emb, + guidance=guidance, + text_ids=text_ids, + image_ids=None, + controlnet_frames=tiled_controlnet_frames, + tiled=False, + **kwargs + ) + return FastTileWorker().tiled_forward( + flux_forward_fn, + latents, + tile_size=tile_size, + tile_stride=tile_stride, + tile_device=latents.device, + tile_dtype=latents.dtype + ) + + hidden_states = latents + + # ControlNet + if controlnet is not None and controlnet_frames is not None: + controlnet_extra_kwargs = { + "hidden_states": hidden_states, + "timestep": timestep, + "prompt_emb": prompt_emb, + "pooled_prompt_emb": pooled_prompt_emb, + "guidance": guidance, + "text_ids": text_ids, + "image_ids": image_ids, + "tiled": tiled, + "tile_size": tile_size, + "tile_stride": tile_stride, + } + if id_emb is not None: + controlnet_text_ids = torch.zeros(id_emb.shape[0], id_emb.shape[1], 3).to(device=hidden_states.device, dtype=hidden_states.dtype) + controlnet_extra_kwargs.update({"prompt_emb": id_emb, 'text_ids': controlnet_text_ids, 'guidance': infinityou_guidance}) + controlnet_res_stack, controlnet_single_res_stack = controlnet( + controlnet_frames, **controlnet_extra_kwargs + ) + + # Flex + if flex_condition is not None: + if timestep.tolist()[0] >= flex_control_stop_timestep: + hidden_states = torch.concat([hidden_states, flex_condition], dim=1) + else: + hidden_states = torch.concat([hidden_states, flex_uncondition], dim=1) + + # Step1x + if step1x_llm_embedding is not None: + prompt_emb, pooled_prompt_emb = step1x_connector(step1x_llm_embedding, timestep / 1000, step1x_mask) + text_ids = torch.zeros((1, prompt_emb.shape[1], 3), dtype=prompt_emb.dtype, device=prompt_emb.device) + + if image_ids is None: + image_ids = dit.prepare_image_ids(hidden_states) + + conditioning = dit.time_embedder(timestep, hidden_states.dtype) + dit.pooled_text_embedder(pooled_prompt_emb) + if dit.guidance_embedder is not None: + guidance = guidance * 1000 + conditioning = conditioning + dit.guidance_embedder(guidance, hidden_states.dtype) + + height, width = hidden_states.shape[-2:] + hidden_states = dit.patchify(hidden_states) + + # Step1x + if step1x_reference_latents is not None: + step1x_reference_image_ids = dit.prepare_image_ids(step1x_reference_latents) + step1x_reference_latents = dit.patchify(step1x_reference_latents) + image_ids = torch.concat([image_ids, step1x_reference_image_ids], dim=-2) + hidden_states = torch.concat([hidden_states, step1x_reference_latents], dim=1) + + hidden_states = dit.x_embedder(hidden_states) + + if entity_prompt_emb is not None and entity_masks is not None: + prompt_emb, image_rotary_emb, attention_mask = dit.process_entity_masks(hidden_states, prompt_emb, entity_prompt_emb, entity_masks, text_ids, image_ids) + else: + prompt_emb = dit.context_embedder(prompt_emb) + image_rotary_emb = dit.pos_embedder(torch.cat((text_ids, image_ids), dim=1)) + attention_mask = None + + # TeaCache + if tea_cache is not None: + tea_cache_update = tea_cache.check(dit, hidden_states, conditioning) + else: + tea_cache_update = False + + if tea_cache_update: + hidden_states = tea_cache.update(hidden_states) + else: + # Joint Blocks + for block_id, block in enumerate(dit.blocks): + hidden_states, prompt_emb = block( + hidden_states, + prompt_emb, + conditioning, + image_rotary_emb, + attention_mask, + ipadapter_kwargs_list=ipadapter_kwargs_list.get(block_id, None) + ) + # ControlNet + if controlnet is not None and controlnet_frames is not None: + hidden_states = hidden_states + controlnet_res_stack[block_id] + + # Single Blocks + hidden_states = torch.cat([prompt_emb, hidden_states], dim=1) + num_joint_blocks = len(dit.blocks) + for block_id, block in enumerate(dit.single_blocks): + hidden_states, prompt_emb = block( + hidden_states, + prompt_emb, + conditioning, + image_rotary_emb, + attention_mask, + ipadapter_kwargs_list=ipadapter_kwargs_list.get(block_id + num_joint_blocks, None) + ) + # ControlNet + if controlnet is not None and controlnet_frames is not None: + hidden_states[:, prompt_emb.shape[1]:] = hidden_states[:, prompt_emb.shape[1]:] + controlnet_single_res_stack[block_id] + hidden_states = hidden_states[:, prompt_emb.shape[1]:] + + if tea_cache is not None: + tea_cache.store(hidden_states) + + hidden_states = dit.final_norm_out(hidden_states, conditioning) + hidden_states = dit.final_proj_out(hidden_states) + + # Step1x + if step1x_reference_latents is not None: + hidden_states = hidden_states[:, :hidden_states.shape[1] // 2] + + hidden_states = dit.unpatchify(hidden_states, height, width) + + return hidden_states diff --git a/diffsynth/pipelines/wan_video_new.py b/diffsynth/pipelines/wan_video_new.py index 4a7a2a2..a93694c 100644 --- a/diffsynth/pipelines/wan_video_new.py +++ b/diffsynth/pipelines/wan_video_new.py @@ -168,24 +168,44 @@ class ModelConfig: def download_if_necessary(self, local_model_path="./models", skip_download=False, use_usp=False): if self.path is None: + # Check model_id and origin_file_pattern if self.model_id is None or self.origin_file_pattern is None: raise ValueError(f"""No valid model files. Please use `ModelConfig(path="xxx")` or `ModelConfig(model_id="xxx/yyy", origin_file_pattern="zzz")`.""") + + # Skip if not in rank 0 if use_usp: import torch.distributed as dist skip_download = dist.get_rank() != 0 + + # Check whether the origin path is a folder + if isinstance(self.origin_file_pattern, str) and self.origin_file_pattern.endswith("/"): + allow_file_pattern = self.origin_file_pattern + "*" + is_folder = True + else: + allow_file_pattern = self.origin_file_pattern + is_folder = False + + # Download if not skip_download: downloaded_files = glob.glob(self.origin_file_pattern, root_dir=os.path.join(local_model_path, self.model_id)) snapshot_download( self.model_id, local_dir=os.path.join(local_model_path, self.model_id), - allow_file_pattern=self.origin_file_pattern, + allow_file_pattern=allow_file_pattern, ignore_file_pattern=downloaded_files, local_files_only=False ) + + # Let rank 1, 2, ... wait for rank 0 if use_usp: import torch.distributed as dist dist.barrier(device_ids=[dist.get_rank()]) - self.path = glob.glob(os.path.join(local_model_path, self.model_id, self.origin_file_pattern)) + + # Return downloaded files + if is_folder: + self.path = os.path.join(local_model_path, self.model_id, self.origin_file_pattern) + else: + self.path = glob.glob(os.path.join(local_model_path, self.model_id, self.origin_file_pattern)) if isinstance(self.path, list) and len(self.path) == 1: self.path = self.path[0] @@ -614,11 +634,17 @@ class PipelineUnitRunner: elif unit.seperate_cfg: # Positive side processor_inputs = {name: inputs_posi.get(name_) for name, name_ in unit.input_params_posi.items()} + if unit.input_params is not None: + for name in unit.input_params: + processor_inputs[name] = inputs_shared.get(name) processor_outputs = unit.process(pipe, **processor_inputs) inputs_posi.update(processor_outputs) # Negative side if inputs_shared["cfg_scale"] != 1: processor_inputs = {name: inputs_nega.get(name_) for name, name_ in unit.input_params_nega.items()} + if unit.input_params is not None: + for name in unit.input_params: + processor_inputs[name] = inputs_shared.get(name) processor_outputs = unit.process(pipe, **processor_inputs) inputs_nega.update(processor_outputs) else: From 1788d50f0aaa9c22e9a7a86a4bcad901d196a4c2 Mon Sep 17 00:00:00 2001 From: Artiprocher Date: Thu, 19 Jun 2025 15:04:30 +0800 Subject: [PATCH 02/14] flux-refactor --- {diffsynth => examples}/flux/FLUX.1-dev.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {diffsynth => examples}/flux/FLUX.1-dev.py (100%) diff --git a/diffsynth/flux/FLUX.1-dev.py b/examples/flux/FLUX.1-dev.py similarity index 100% rename from diffsynth/flux/FLUX.1-dev.py rename to examples/flux/FLUX.1-dev.py From 1b3c204d209f7db1d0f181c992e41f0efa8f3302 Mon Sep 17 00:00:00 2001 From: mi804 <1576993271@qq.com> Date: Fri, 20 Jun 2025 14:49:09 +0800 Subject: [PATCH 03/14] flux_ipadapter_refactor --- diffsynth/pipelines/flux_image_new.py | 28 +++++++++++++++++++++++++- examples/flux/flux_ipadapter.py | 29 +++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 examples/flux/flux_ipadapter.py diff --git a/diffsynth/pipelines/flux_image_new.py b/diffsynth/pipelines/flux_image_new.py index bab84b8..3a1d382 100644 --- a/diffsynth/pipelines/flux_image_new.py +++ b/diffsynth/pipelines/flux_image_new.py @@ -43,6 +43,7 @@ class FluxImagePipeline(BasePipeline): FluxImageUnit_InputImageEmbedder(), FluxImageUnit_ImageIDs(), FluxImageUnit_EmbeddedGuidanceEmbedder(), + FluxImageUnit_IPAdapter(), ] self.model_fn = model_fn_flux_image @@ -98,7 +99,9 @@ class FluxImagePipeline(BasePipeline): pipe.vae_decoder = model_manager.fetch_model("flux_vae_decoder") pipe.vae_encoder = model_manager.fetch_model("flux_vae_encoder") pipe.prompter.fetch_models(pipe.text_encoder_1, pipe.text_encoder_2) - + pipe.ipadapter = model_manager.fetch_model("flux_ipadapter") + pipe.ipadapter_image_encoder = model_manager.fetch_model("siglip_vision_model") + return pipe @@ -294,6 +297,29 @@ class FluxImageUnit_EmbeddedGuidanceEmbedder(PipelineUnit): return {"guidance": guidance} +class FluxImageUnit_IPAdapter(PipelineUnit): + def __init__(self): + super().__init__( + take_over=True, + onload_model_names=("ipadapter_image_encoder", "ipadapter") + ) + + def process(self, pipe: FluxImagePipeline, inputs_shared, inputs_posi, inputs_nega): + ipadapter_images, ipadapter_scale = inputs_shared.get("ipadapter_images", None), inputs_shared.get("ipadapter_scale", 1.0) + if ipadapter_images is None: + return inputs_shared, inputs_posi, inputs_nega + + pipe.load_models_to_device(self.onload_model_names) + images = [image.convert("RGB").resize((384, 384), resample=3) for image in ipadapter_images] + images = [pipe.preprocess_image(image).to(device=pipe.device, dtype=pipe.torch_dtype) for image in images] + ipadapter_images = torch.cat(images, dim=0) + ipadapter_image_encoding = pipe.ipadapter_image_encoder(ipadapter_images).pooler_output + + inputs_posi.update({"ipadapter_kwargs_list": pipe.ipadapter(ipadapter_image_encoding, scale=ipadapter_scale)}) + if inputs_shared.get("cfg_scale", 1.0) != 1.0: + inputs_nega.update({"ipadapter_kwargs_list": pipe.ipadapter(torch.zeros_like(ipadapter_image_encoding))}) + return inputs_shared, inputs_posi, inputs_nega + class TeaCache: def __init__(self, num_inference_steps, rel_l1_thresh): diff --git a/examples/flux/flux_ipadapter.py b/examples/flux/flux_ipadapter.py new file mode 100644 index 0000000..6214e4d --- /dev/null +++ b/examples/flux/flux_ipadapter.py @@ -0,0 +1,29 @@ +import torch +from PIL import Image +from diffsynth import save_video, VideoData, download_models +from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig +from modelscope import dataset_snapshot_download + +#TODO: repalce the local path with model_id +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), + ModelConfig(model_id="InstantX/FLUX.1-dev-IP-Adapter", origin_file_pattern="ip-adapter.bin"), + ModelConfig(path="models/IpAdapter/InstantX/FLUX.1-dev-IP-Adapter/image_encoder") + ], +) + +seed = 42 +origin_prompt = "a rabbit in a garden, colorful flowers" +image = pipe(prompt=origin_prompt, height=1280, width=960, seed=seed) +image.save("style image.jpg") + +torch.manual_seed(seed) +image = pipe(prompt="A piggy", height=1280, width=960, seed=seed, + ipadapter_images=[image], ipadapter_scale=0.7) +image.save("A piggy.jpg") From 6d5f8b74239de653ccda3bf9e48a05b809db2a1d Mon Sep 17 00:00:00 2001 From: mi804 <1576993271@qq.com> Date: Fri, 20 Jun 2025 16:53:41 +0800 Subject: [PATCH 04/14] flux_eligen_refactor --- diffsynth/lora/flux_lora.py | 13 +++ diffsynth/pipelines/flux_image_new.py | 57 +++++++++- examples/flux/flux_entity_control.py | 147 ++++++++++++++++++++++++++ 3 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 diffsynth/lora/flux_lora.py create mode 100644 examples/flux/flux_entity_control.py diff --git a/diffsynth/lora/flux_lora.py b/diffsynth/lora/flux_lora.py new file mode 100644 index 0000000..899160f --- /dev/null +++ b/diffsynth/lora/flux_lora.py @@ -0,0 +1,13 @@ +import torch +from diffsynth.lora import GeneralLoRALoader +from diffsynth.models.lora import FluxLoRAFromCivitai + + +class FluxLoRALoader(GeneralLoRALoader): + def __init__(self, device="cpu", torch_dtype=torch.float32): + super().__init__(device=device, torch_dtype=torch_dtype) + self.loader = FluxLoRAFromCivitai() + + def load(self, model: torch.nn.Module, state_dict_lora, alpha=1.0): + lora_prefix, model_resource = self.loader.match(model, state_dict_lora) + self.loader.load(model, state_dict_lora, lora_prefix, alpha=alpha, model_resource=model_resource) \ No newline at end of file diff --git a/diffsynth/pipelines/flux_image_new.py b/diffsynth/pipelines/flux_image_new.py index 3a1d382..b27a7d3 100644 --- a/diffsynth/pipelines/flux_image_new.py +++ b/diffsynth/pipelines/flux_image_new.py @@ -14,9 +14,10 @@ from typing_extensions import Literal from ..schedulers import FlowMatchScheduler from ..prompters import FluxPrompter -from ..models import ModelManager, SD3TextEncoder1, FluxTextEncoder2, FluxDiT, FluxVAEEncoder, FluxVAEDecoder +from ..models import ModelManager, load_state_dict, SD3TextEncoder1, FluxTextEncoder2, FluxDiT, FluxVAEEncoder, FluxVAEDecoder from ..models.tiler import FastTileWorker from .wan_video_new import BasePipeline, ModelConfig, PipelineUnitRunner, PipelineUnit +from ..lora.flux_lora import FluxLoRALoader @@ -44,12 +45,15 @@ class FluxImagePipeline(BasePipeline): FluxImageUnit_ImageIDs(), FluxImageUnit_EmbeddedGuidanceEmbedder(), FluxImageUnit_IPAdapter(), + FluxImageUnit_EntityControl(), ] self.model_fn = model_fn_flux_image def load_lora(self, module, path, alpha=1): - pass + loader = FluxLoRALoader(torch_dtype=self.torch_dtype, device=self.device) + lora = load_state_dict(path, torch_dtype=self.torch_dtype, device=self.device) + loader.load(module, lora, alpha=alpha) def training_loss(self, **inputs): @@ -321,6 +325,55 @@ class FluxImageUnit_IPAdapter(PipelineUnit): return inputs_shared, inputs_posi, inputs_nega +class FluxImageUnit_EntityControl(PipelineUnit): + def __init__(self): + super().__init__( + take_over=True, + onload_model_names=("text_encoder_1", "text_encoder_2") + ) + + def preprocess_masks(self, pipe, masks, height, width, dim): + out_masks = [] + for mask in masks: + mask = pipe.preprocess_image(mask.resize((width, height), resample=Image.NEAREST)).mean(dim=1, keepdim=True) > 0 + mask = mask.repeat(1, dim, 1, 1).to(device=pipe.device, dtype=pipe.torch_dtype) + out_masks.append(mask) + return out_masks + + def prepare_entity_inputs(self, pipe, entity_prompts, entity_masks, width, height, t5_sequence_length=512): + entity_masks = self.preprocess_masks(pipe, entity_masks, height//8, width//8, 1) + entity_masks = torch.cat(entity_masks, dim=0).unsqueeze(0) # b, n_mask, c, h, w + + prompt_emb, _, _ = pipe.prompter.encode_prompt( + entity_prompts, device=pipe.device, t5_sequence_length=t5_sequence_length + ) + return prompt_emb.unsqueeze(0), entity_masks + + def prepare_eligen(self, pipe, prompt_emb_nega, eligen_entity_prompts, eligen_entity_masks, width, height, t5_sequence_length, enable_eligen_on_negative, cfg_scale): + entity_prompt_emb_posi, entity_masks_posi = self.prepare_entity_inputs(pipe, eligen_entity_prompts, eligen_entity_masks, width, height, t5_sequence_length) + if enable_eligen_on_negative and cfg_scale != 1.0: + entity_prompt_emb_nega = prompt_emb_nega['prompt_emb'].unsqueeze(1).repeat(1, entity_masks_posi.shape[1], 1, 1) + entity_masks_nega = entity_masks_posi + else: + entity_prompt_emb_nega, entity_masks_nega = None, None + eligen_kwargs_posi = {"entity_prompt_emb": entity_prompt_emb_posi, "entity_masks": entity_masks_posi} + eligen_kwargs_nega = {"entity_prompt_emb": entity_prompt_emb_nega, "entity_masks": entity_masks_nega} + return eligen_kwargs_posi, eligen_kwargs_nega + + def process(self, pipe: FluxImagePipeline, inputs_shared, inputs_posi, inputs_nega): + eligen_entity_prompts, eligen_entity_masks = inputs_shared.get("eligen_entity_prompts", None), inputs_shared.get("eligen_entity_masks", None) + if eligen_entity_prompts is None or eligen_entity_masks is None: + return inputs_shared, inputs_posi, inputs_nega + pipe.load_models_to_device(self.onload_model_names) + eligen_kwargs_posi, eligen_kwargs_nega = self.prepare_eligen(pipe, inputs_nega, + eligen_entity_prompts, eligen_entity_masks, inputs_shared["width"], inputs_shared["height"], + inputs_shared["t5_sequence_length"], inputs_shared["eligen_enable_on_negative"], inputs_shared["cfg_scale"]) + inputs_posi.update(eligen_kwargs_posi) + if inputs_shared.get("cfg_scale", 1.0) != 1.0: + inputs_nega.update(eligen_kwargs_nega) + return inputs_shared, inputs_posi, inputs_nega + + class TeaCache: def __init__(self, num_inference_steps, rel_l1_thresh): self.num_inference_steps = num_inference_steps diff --git a/examples/flux/flux_entity_control.py b/examples/flux/flux_entity_control.py new file mode 100644 index 0000000..380cd07 --- /dev/null +++ b/examples/flux/flux_entity_control.py @@ -0,0 +1,147 @@ +import random +import torch +from PIL import Image, ImageDraw, ImageFont +from diffsynth import download_customized_models +from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig +from modelscope import dataset_snapshot_download + + +def visualize_masks(image, masks, mask_prompts, output_path, font_size=35, use_random_colors=False): + # Create a blank image for overlays + overlay = Image.new('RGBA', image.size, (0, 0, 0, 0)) + + colors = [ + (165, 238, 173, 80), + (76, 102, 221, 80), + (221, 160, 77, 80), + (204, 93, 71, 80), + (145, 187, 149, 80), + (134, 141, 172, 80), + (157, 137, 109, 80), + (153, 104, 95, 80), + (165, 238, 173, 80), + (76, 102, 221, 80), + (221, 160, 77, 80), + (204, 93, 71, 80), + (145, 187, 149, 80), + (134, 141, 172, 80), + (157, 137, 109, 80), + (153, 104, 95, 80), + ] + # Generate random colors for each mask + if use_random_colors: + colors = [(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255), 80) for _ in range(len(masks))] + + # Font settings + try: + font = ImageFont.truetype("arial", font_size) # Adjust as needed + except IOError: + font = ImageFont.load_default(font_size) + + # Overlay each mask onto the overlay image + for mask, mask_prompt, color in zip(masks, mask_prompts, colors): + # Convert mask to RGBA mode + mask_rgba = mask.convert('RGBA') + mask_data = mask_rgba.getdata() + new_data = [(color if item[:3] == (255, 255, 255) else (0, 0, 0, 0)) for item in mask_data] + mask_rgba.putdata(new_data) + + # Draw the mask prompt text on the mask + draw = ImageDraw.Draw(mask_rgba) + mask_bbox = mask.getbbox() # Get the bounding box of the mask + text_position = (mask_bbox[0] + 10, mask_bbox[1] + 10) # Adjust text position based on mask position + draw.text(text_position, mask_prompt, fill=(255, 255, 255, 255), font=font) + + # Alpha composite the overlay with this mask + overlay = Image.alpha_composite(overlay, mask_rgba) + + # Composite the overlay onto the original image + result = Image.alpha_composite(image.convert('RGBA'), overlay) + + # Save or display the resulting image + result.save(output_path) + + return result + +def example(pipe, seeds, example_id, global_prompt, entity_prompts): + dataset_snapshot_download(dataset_id="DiffSynth-Studio/examples_in_diffsynth", local_dir="./", allow_file_pattern=f"data/examples/eligen/entity_control/example_{example_id}/*.png") + masks = [Image.open(f"./data/examples/eligen/entity_control/example_{example_id}/{i}.png").convert('RGB') for i in range(len(entity_prompts))] + negative_prompt = "worst quality, low quality, monochrome, zombie, interlocked fingers, Aissist, cleavage, nsfw," + for seed in seeds: + # generate image + image = pipe( + prompt=global_prompt, + cfg_scale=3.0, + negative_prompt=negative_prompt, + num_inference_steps=50, + embedded_guidance=3.5, + seed=seed, + height=1024, + width=1024, + eligen_entity_prompts=entity_prompts, + eligen_entity_masks=masks, + ) + image.save(f"eligen_example_{example_id}_{seed}.png") + visualize_masks(image, masks, entity_prompts, f"eligen_example_{example_id}_mask_{seed}.png") + + +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), + ], +) + +download_from_modelscope = True +if download_from_modelscope: + model_id = "DiffSynth-Studio/Eligen" + downloading_priority = ["ModelScope"] +else: + model_id = "modelscope/EliGen" + downloading_priority = ["HuggingFace"] +EliGen_path = download_customized_models( + model_id=model_id, + origin_file_path="model_bf16.safetensors", + local_dir="models/lora/entity_control", + downloading_priority=downloading_priority)[0] +pipe.load_lora(pipe.dit, EliGen_path, alpha=1) + +# example 1 +global_prompt = "A breathtaking beauty of Raja Ampat by the late-night moonlight , one beautiful woman from behind wearing a pale blue long dress with soft glow, sitting at the top of a cliff looking towards the beach,pastell light colors, a group of small distant birds flying in far sky, a boat sailing on the sea, best quality, realistic, whimsical, fantastic, splash art, intricate detailed, hyperdetailed, maximalist style, photorealistic, concept art, sharp focus, harmony, serenity, tranquility, soft pastell colors,ambient occlusion, cozy ambient lighting, masterpiece, liiv1, linquivera, metix, mentixis, masterpiece, award winning, view from above\n" +entity_prompts = ["cliff", "sea", "moon", "sailing boat", "a seated beautiful woman", "pale blue long dress with soft glow"] +example(pipe, [0], 1, global_prompt, entity_prompts) + +# example 2 +global_prompt = "samurai girl wearing a kimono, she's holding a sword glowing with red flame, her long hair is flowing in the wind, she is looking at a small bird perched on the back of her hand. ultra realist style. maximum image detail. maximum realistic render." +entity_prompts = ["flowing hair", "sword glowing with red flame", "A cute bird", "blue belt"] +example(pipe, [0], 2, global_prompt, entity_prompts) + +# example 3 +global_prompt = "Image of a neverending staircase up to a mysterious palace in the sky, The ancient palace stood majestically atop a mist-shrouded mountain, sunrise, two traditional monk walk in the stair looking at the sunrise, fog,see-through, best quality, whimsical, fantastic, splash art, intricate detailed, hyperdetailed, photorealistic, concept art, harmony, serenity, tranquility, ambient occlusion, halation, cozy ambient lighting, dynamic lighting,masterpiece, liiv1, linquivera, metix, mentixis, masterpiece, award winning," +entity_prompts = ["ancient palace", "stone staircase with railings", "a traditional monk", "a traditional monk"] +example(pipe, [27], 3, global_prompt, entity_prompts) + +# example 4 +global_prompt = "A beautiful girl wearing shirt and shorts in the street, holding a sign 'Entity Control'" +entity_prompts = ["A beautiful girl", "sign 'Entity Control'", "shorts", "shirt"] +example(pipe, [21], 4, global_prompt, entity_prompts) + +# example 5 +global_prompt = "A captivating, dramatic scene in a painting that exudes mystery and foreboding. A white sky, swirling blue clouds, and a crescent yellow moon illuminate a solitary woman standing near the water's edge. Her long dress flows in the wind, silhouetted against the eerie glow. The water mirrors the fiery sky and moonlight, amplifying the uneasy atmosphere." +entity_prompts = ["crescent yellow moon", "a solitary woman", "water", "swirling blue clouds"] +example(pipe, [0], 5, global_prompt, entity_prompts) + +# example 6 +global_prompt = "Snow White and the 6 Dwarfs." +entity_prompts = ["Dwarf 1", "Dwarf 2", "Dwarf 3", "Snow White", "Dwarf 4", "Dwarf 5", "Dwarf 6"] +example(pipe, [8], 6, global_prompt, entity_prompts) + +# example 7, same prompt with different seeds +seeds = range(5, 9) +global_prompt = "A beautiful woman wearing white dress, holding a mirror, with a warm light background;" +entity_prompts = ["A beautiful woman", "mirror", "necklace", "glasses", "earring", "white dress", "jewelry headpiece"] +example(pipe, seeds, 7, global_prompt, entity_prompts) From cc6cd267334d637dd49f25c26dd39bb69b89088e Mon Sep 17 00:00:00 2001 From: "lzw478614@alibaba-inc.com" Date: Mon, 23 Jun 2025 17:06:00 +0800 Subject: [PATCH 05/14] step1x, teacache, flex refactor --- diffsynth/pipelines/flux_image_new.py | 78 ++++++++++++++++++++++++++- examples/flux/flex_text_to_image.py | 50 +++++++++++++++++ examples/flux/flux_teacache.py | 24 +++++++++ examples/flux/step1x.py | 44 +++++++++++++++ 4 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 examples/flux/flex_text_to_image.py create mode 100644 examples/flux/flux_teacache.py create mode 100644 examples/flux/step1x.py diff --git a/diffsynth/pipelines/flux_image_new.py b/diffsynth/pipelines/flux_image_new.py index b27a7d3..7773f7b 100644 --- a/diffsynth/pipelines/flux_image_new.py +++ b/diffsynth/pipelines/flux_image_new.py @@ -15,6 +15,7 @@ from typing_extensions import Literal from ..schedulers import FlowMatchScheduler from ..prompters import FluxPrompter from ..models import ModelManager, load_state_dict, SD3TextEncoder1, FluxTextEncoder2, FluxDiT, FluxVAEEncoder, FluxVAEDecoder +from ..models.step1x_connector import Qwen2Connector from ..models.tiler import FastTileWorker from .wan_video_new import BasePipeline, ModelConfig, PipelineUnitRunner, PipelineUnit from ..lora.flux_lora import FluxLoRALoader @@ -36,7 +37,9 @@ class FluxImagePipeline(BasePipeline): self.vae_decoder: FluxVAEDecoder = None self.vae_encoder: FluxVAEEncoder = None self.unit_runner = PipelineUnitRunner() - self.in_iteration_models = ("dit", ) + self.qwenvl = None + self.step1x_connector: Qwen2Connector = None + self.in_iteration_models = ("dit", "step1x_connector") self.units = [ FluxImageUnit_ShapeChecker(), FluxImageUnit_NoiseInitializer(), @@ -46,6 +49,9 @@ class FluxImagePipeline(BasePipeline): FluxImageUnit_EmbeddedGuidanceEmbedder(), FluxImageUnit_IPAdapter(), FluxImageUnit_EntityControl(), + FluxImageUnit_TeaCache(), + FluxImageUnit_Flex(), + FluxImageUnit_Step1x(), ] self.model_fn = model_fn_flux_image @@ -105,6 +111,9 @@ class FluxImagePipeline(BasePipeline): pipe.prompter.fetch_models(pipe.text_encoder_1, pipe.text_encoder_2) pipe.ipadapter = model_manager.fetch_model("flux_ipadapter") pipe.ipadapter_image_encoder = model_manager.fetch_model("siglip_vision_model") + # Step1x + pipe.qwenvl = model_manager.fetch_model("qwenvl") + pipe.step1x_connector = model_manager.fetch_model("step1x_connector") return pipe @@ -374,6 +383,73 @@ class FluxImageUnit_EntityControl(PipelineUnit): return inputs_shared, inputs_posi, inputs_nega +class FluxImageUnit_Step1x(PipelineUnit): + def __init__(self): + super().__init__(take_over=True,onload_model_names=("qwenvl","vae_encoder")) + + def process(self, pipe: FluxImagePipeline, inputs_shared: dict, inputs_posi: dict, inputs_nega: dict): + image = inputs_shared.get("step1x_reference_image",None) + if image is None: + return inputs_shared, inputs_posi, inputs_nega + else: + pipe.load_models_to_device(self.onload_model_names) + prompt = inputs_posi["prompt"] + nega_prompt = inputs_nega["negative_prompt"] + captions = [prompt, nega_prompt] + ref_images = [image, image] + embs, masks = pipe.qwenvl(captions, ref_images) + image = pipe.preprocess_image(image).to(device=pipe.device, dtype=pipe.torch_dtype) + image = pipe.vae_encoder(image) + inputs_posi.update({"step1x_llm_embedding": embs[0:1], "step1x_mask": masks[0:1], "step1x_reference_latents": image}) + inputs_nega.update({"step1x_llm_embedding": embs[1:2], "step1x_mask": masks[1:2], "step1x_reference_latents": image}) + return inputs_shared, inputs_posi, inputs_nega + + +class FluxImageUnit_TeaCache(PipelineUnit): + def __init__(self): + super().__init__(input_params=("num_inference_steps","tea_cache_l1_thresh")) + + def process(self, pipe: FluxImagePipeline, num_inference_steps, tea_cache_l1_thresh): + if tea_cache_l1_thresh is None: + return {} + else: + return {"tea_cache": TeaCache(num_inference_steps=num_inference_steps, rel_l1_thresh=tea_cache_l1_thresh)} + +class FluxImageUnit_Flex(PipelineUnit): + def __init__(self): + super().__init__( + input_params=("latents", "flex_inpaint_image", "flex_inpaint_mask", "flex_control_image", "flex_control_strength", "flex_control_stop", "tiled", "tile_size", "tile_stride"), + onload_model_names=("vae_encoder",) + ) + + def process(self, pipe: FluxImagePipeline, latents, flex_inpaint_image, flex_inpaint_mask, flex_control_image, flex_control_strength, flex_control_stop, tiled, tile_size, tile_stride): + if pipe.dit.input_dim == 196: + pipe.load_models_to_device(self.onload_model_names) + if flex_inpaint_image is None: + flex_inpaint_image = torch.zeros_like(latents) + else: + flex_inpaint_image = pipe.preprocess_image(flex_inpaint_image).to(device=pipe.device, dtype=pipe.torch_dtype) + flex_inpaint_image = pipe.vae_encoder(flex_inpaint_image, tiled=tiled, tile_size=tile_size, tile_stride=tile_stride) + if flex_inpaint_mask is None: + flex_inpaint_mask = torch.ones_like(latents)[:, 0:1, :, :] + else: + flex_inpaint_mask = flex_inpaint_mask.resize((latents.shape[3], latents.shape[2])) + flex_inpaint_mask = pipe.preprocess_image(flex_inpaint_mask).to(device=pipe.device, dtype=pipe.torch_dtype) + flex_inpaint_mask = (flex_inpaint_mask[:, 0:1, :, :] + 1) / 2 + flex_inpaint_image = flex_inpaint_image * (1 - flex_inpaint_mask) + if flex_control_image is None: + flex_control_image = torch.zeros_like(latents) + else: + flex_control_image = pipe.preprocess_image(flex_control_image).to(device=pipe.device, dtype=pipe.torch_dtype) + flex_control_image = pipe.vae_encoder(flex_control_image, tiled=tiled, tile_size=tile_size, tile_stride=tile_stride) * flex_control_strength + flex_condition = torch.concat([flex_inpaint_image, flex_inpaint_mask, flex_control_image], dim=1) + flex_uncondition = torch.concat([flex_inpaint_image, flex_inpaint_mask, torch.zeros_like(flex_control_image)], dim=1) + flex_control_stop_timestep = pipe.scheduler.timesteps[int(flex_control_stop * (len(pipe.scheduler.timesteps) - 1))] + return {"flex_condition": flex_condition, "flex_uncondition": flex_uncondition, "flex_control_stop_timestep": flex_control_stop_timestep} + else: + return {} + + class TeaCache: def __init__(self, num_inference_steps, rel_l1_thresh): self.num_inference_steps = num_inference_steps diff --git a/examples/flux/flex_text_to_image.py b/examples/flux/flex_text_to_image.py new file mode 100644 index 0000000..aa33641 --- /dev/null +++ b/examples/flux/flex_text_to_image.py @@ -0,0 +1,50 @@ +import torch +from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig +from diffsynth.controlnets.processors import Annotator +import numpy as np +from PIL import Image + + +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="ostris/Flex.2-preview", origin_file_pattern="Flex.2-preview.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), + ], +) + +image = pipe( + prompt="portrait of a beautiful Asian girl, long hair, red t-shirt, sunshine, beach", + num_inference_steps=50, embedded_guidance=3.5, + seed=0 +) +image.save(f"image_1.jpg") + +mask = np.zeros((1024, 1024, 3), dtype=np.uint8) +mask[200:400, 400:700] = 255 +mask = Image.fromarray(mask) +mask.save(f"image_mask.jpg") + +inpaint_image = image + +image = pipe( + prompt="portrait of a beautiful Asian girl with sunglasses, long hair, red t-shirt, sunshine, beach", + num_inference_steps=50, embedded_guidance=3.5, + flex_inpaint_image=inpaint_image, flex_inpaint_mask=mask, + seed=4 +) +image.save(f"image_2_new.jpg") + +control_image = Annotator("canny")(image) +control_image.save("image_control.jpg") + +image = pipe( + prompt="portrait of a beautiful Asian girl with sunglasses, long hair, yellow t-shirt, sunshine, beach", + num_inference_steps=50, embedded_guidance=3.5, + flex_control_image=control_image, + seed=4 +) +image.save(f"image_3_new.jpg") diff --git a/examples/flux/flux_teacache.py b/examples/flux/flux_teacache.py new file mode 100644 index 0000000..a325324 --- /dev/null +++ b/examples/flux/flux_teacache.py @@ -0,0 +1,24 @@ +import torch +from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig + + +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), + ], +) + + +prompt = "CG, masterpiece, best quality, solo, long hair, wavy hair, silver hair, blue eyes, blue dress, medium breasts, dress, underwater, air bubble, floating hair, refraction, portrait. The girl's flowing silver hair shimmers with every color of the rainbow and cascades down, merging with the floating flora around her." + +for tea_cache_l1_thresh in [None, 0.2, 0.4, 0.6, 0.8]: + image = pipe( + prompt=prompt, embedded_guidance=3.5, seed=0, + num_inference_steps=50, tea_cache_l1_thresh=tea_cache_l1_thresh + ) + image.save(f"image_{tea_cache_l1_thresh}.png") diff --git a/examples/flux/step1x.py b/examples/flux/step1x.py new file mode 100644 index 0000000..eca7605 --- /dev/null +++ b/examples/flux/step1x.py @@ -0,0 +1,44 @@ +import torch +from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig +from modelscope import snapshot_download +from PIL import Image +import numpy as np + + +snapshot_download("Qwen/Qwen2.5-VL-7B-Instruct", cache_dir="./models") +snapshot_download("stepfun-ai/Step1X-Edit", cache_dir="./models") + +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(path="models/Qwen/Qwen2.5-VL-7B-Instruct"), + ModelConfig(model_id="stepfun-ai/Step1X-Edit", origin_file_pattern="step1x-edit-i1258.safetensors"), + ModelConfig(model_id="stepfun-ai/Step1X-Edit", origin_file_pattern="vae.safetensors"), + ], +) + + +pipe.enable_vram_management() + +image = Image.fromarray(np.zeros((1248, 832, 3), dtype=np.uint8) + 255) +image = pipe( + prompt="draw red flowers in Chinese ink painting style", + step1x_reference_image=image, + width=832, height=1248, cfg_scale=6, + seed=1, + rand_device='cuda' +) +image.save("image_1.jpg") + + + +image = pipe( + prompt="add more flowers in Chinese ink painting style", + step1x_reference_image=image, + width=832, height=1248, cfg_scale=6, + seed=2, + rand_device='cuda' +) +image.save("image_2.jpg") + From c4e50335320fdc2a188cfb305718152b5ca4a76a Mon Sep 17 00:00:00 2001 From: Artiprocher Date: Mon, 23 Jun 2025 21:01:53 +0800 Subject: [PATCH 06/14] flux controlnet --- diffsynth/pipelines/flux_image_new.py | 195 ++++++++++++++---- .../FLUX.1-dev-Controlnet-Inpainting-Beta.py | 37 ++++ .../flux/FLUX.1-dev-Controlnet-Union-alpha.py | 40 ++++ .../flux/FLUX.1-dev-Controlnet-Upscaler.py | 33 +++ examples/flux/FLUX.1-dev.py | 15 +- 5 files changed, 271 insertions(+), 49 deletions(-) create mode 100644 examples/flux/FLUX.1-dev-Controlnet-Inpainting-Beta.py create mode 100644 examples/flux/FLUX.1-dev-Controlnet-Union-alpha.py create mode 100644 examples/flux/FLUX.1-dev-Controlnet-Upscaler.py diff --git a/diffsynth/pipelines/flux_image_new.py b/diffsynth/pipelines/flux_image_new.py index b27a7d3..ac3256e 100644 --- a/diffsynth/pipelines/flux_image_new.py +++ b/diffsynth/pipelines/flux_image_new.py @@ -15,12 +15,59 @@ from typing_extensions import Literal from ..schedulers import FlowMatchScheduler from ..prompters import FluxPrompter from ..models import ModelManager, load_state_dict, SD3TextEncoder1, FluxTextEncoder2, FluxDiT, FluxVAEEncoder, FluxVAEDecoder +from ..models.flux_controlnet import FluxControlNet +from ..models.flux_ipadapter import FluxIpAdapter from ..models.tiler import FastTileWorker from .wan_video_new import BasePipeline, ModelConfig, PipelineUnitRunner, PipelineUnit from ..lora.flux_lora import FluxLoRALoader +@dataclass +class ControlNetInput: + controlnet_id: int = 0 + scale: float = 1.0 + start: float = 1.0 + end: float = 0.0 + image: Image.Image = None + inpaint_mask: Image.Image = None + processor_id: str = None + + + +class MultiControlNet(torch.nn.Module): + def __init__(self, models: list[FluxControlNet]): + super().__init__() + self.models = torch.nn.ModuleList(models) + + def process_single_controlnet(self, controlnet_input: ControlNetInput, conditioning: torch.Tensor, **kwargs): + model = self.models[controlnet_input.controlnet_id] + res_stack, single_res_stack = model( + controlnet_conditioning=conditioning, + processor_id=controlnet_input.processor_id, + **kwargs + ) + res_stack = [res * controlnet_input.scale for res in res_stack] + single_res_stack = [res * controlnet_input.scale for res in single_res_stack] + return res_stack, single_res_stack + + def forward(self, conditionings: list[torch.Tensor], controlnet_inputs: list[ControlNetInput], progress_id, num_inference_steps, **kwargs): + res_stack, single_res_stack = None, None + for controlnet_input, conditioning in zip(controlnet_inputs, conditionings): + progress = (num_inference_steps - 1 - progress_id) / max(num_inference_steps - 1, 1) + if progress > controlnet_input.start or progress < controlnet_input.end: + continue + res_stack_, single_res_stack_ = self.process_single_controlnet(controlnet_input, conditioning, **kwargs) + if res_stack is None: + res_stack = res_stack_ + single_res_stack = single_res_stack_ + else: + res_stack = [i + j for i, j in zip(res_stack, res_stack_)] + single_res_stack = [i + j for i, j in zip(single_res_stack, single_res_stack_)] + return res_stack, single_res_stack + + + class FluxImagePipeline(BasePipeline): def __init__(self, device="cuda", torch_dtype=torch.bfloat16): @@ -35,8 +82,11 @@ class FluxImagePipeline(BasePipeline): self.dit: FluxDiT = None self.vae_decoder: FluxVAEDecoder = None self.vae_encoder: FluxVAEEncoder = None + self.controlnet: MultiControlNet = None + self.ipadapter: FluxIpAdapter = None + self.ipadapter_image_encoder = None self.unit_runner = PipelineUnitRunner() - self.in_iteration_models = ("dit", ) + self.in_iteration_models = ("dit", "controlnet") self.units = [ FluxImageUnit_ShapeChecker(), FluxImageUnit_NoiseInitializer(), @@ -44,6 +94,7 @@ class FluxImagePipeline(BasePipeline): FluxImageUnit_InputImageEmbedder(), FluxImageUnit_ImageIDs(), FluxImageUnit_EmbeddedGuidanceEmbedder(), + FluxImageUnit_ControlNet(), FluxImageUnit_IPAdapter(), FluxImageUnit_EntityControl(), ] @@ -105,6 +156,13 @@ class FluxImagePipeline(BasePipeline): pipe.prompter.fetch_models(pipe.text_encoder_1, pipe.text_encoder_2) pipe.ipadapter = model_manager.fetch_model("flux_ipadapter") pipe.ipadapter_image_encoder = model_manager.fetch_model("siglip_vision_model") + + # ControlNet + controlnets = [] + for model_name, model in zip(model_manager.model_name, model_manager.model): + if model_name == "flux_controlnet": + controlnets.append(model) + pipe.controlnet = MultiControlNet(controlnets) return pipe @@ -113,57 +171,57 @@ class FluxImagePipeline(BasePipeline): def __call__( self, # Prompt - prompt, - negative_prompt="", - cfg_scale=1.0, - embedded_guidance=3.5, - t5_sequence_length=512, + prompt: str, + negative_prompt: str = "", + cfg_scale: float = 1.0, + embedded_guidance: float = 3.5, + t5_sequence_length: int = 512, # Image - input_image=None, - denoising_strength=1.0, + input_image: Image.Image = None, + denoising_strength: float = 1.0, # Shape - height=1024, - width=1024, + height: int = 1024, + width: int = 1024, # Randomness - seed=None, - rand_device: Optional[str] = "cpu", + seed: int = None, + rand_device: str = "cpu", # Scheduler - sigma_shift=None, + sigma_shift: float = None, # Steps - num_inference_steps=30, + num_inference_steps: int = 30, # local prompts multidiffusion_prompts=(), multidiffusion_masks=(), multidiffusion_scales=(), # ControlNet - controlnet_inputs=None, + controlnet_inputs: list[ControlNetInput] = None, # IP-Adapter - ipadapter_images=None, - ipadapter_scale=1.0, + ipadapter_images: list[Image.Image] = None, + ipadapter_scale: float = 1.0, # EliGen - eligen_entity_prompts=None, - eligen_entity_masks=None, - eligen_enable_on_negative=False, - eligen_enable_inpaint=False, + eligen_entity_prompts: list[str] = None, + eligen_entity_masks: list[Image.Image] = None, + eligen_enable_on_negative: bool = False, + eligen_enable_inpaint: bool = False, # InfiniteYou - infinityou_id_image=None, - infinityou_guidance=1.0, + infinityou_id_image: Image.Image = None, + infinityou_guidance: float = 1.0, # Flex - flex_inpaint_image=None, - flex_inpaint_mask=None, - flex_control_image=None, - flex_control_strength=0.5, - flex_control_stop=0.5, + flex_inpaint_image: Image.Image = None, + flex_inpaint_mask: Image.Image = None, + flex_control_image: Image.Image = None, + flex_control_strength: float = 0.5, + flex_control_stop: float = 0.5, # Step1x - step1x_reference_image=None, + step1x_reference_image: Image.Image = None, # TeaCache - tea_cache_l1_thresh=None, + tea_cache_l1_thresh: float = None, # Tile - tiled=False, - tile_size=128, - tile_stride=64, + tiled: bool = False, + tile_size: int = 128, + tile_stride: int = 64, # Progress bar - progress_bar_cmd=tqdm, + progress_bar_cmd = tqdm, ): # Scheduler self.scheduler.set_timesteps(num_inference_steps, denoising_strength=denoising_strength, shift=sigma_shift) @@ -201,9 +259,9 @@ class FluxImagePipeline(BasePipeline): timestep = timestep.unsqueeze(0).to(dtype=self.torch_dtype, device=self.device) # Inference - noise_pred_posi = self.model_fn(**models, **inputs_shared, **inputs_posi, timestep=timestep) + noise_pred_posi = self.model_fn(**models, **inputs_shared, **inputs_posi, timestep=timestep, progress_id=progress_id) if cfg_scale != 1.0: - noise_pred_nega = self.model_fn(**models, **inputs_shared, **inputs_nega, timestep=timestep) + noise_pred_nega = self.model_fn(**models, **inputs_shared, **inputs_nega, timestep=timestep, progress_id=progress_id) noise_pred = noise_pred_nega + cfg_scale * (noise_pred_posi - noise_pred_nega) else: noise_pred = noise_pred_posi @@ -301,6 +359,49 @@ class FluxImageUnit_EmbeddedGuidanceEmbedder(PipelineUnit): return {"guidance": guidance} + +class FluxImageUnit_ControlNet(PipelineUnit): + def __init__(self): + super().__init__( + input_params=("controlnet_inputs", "tiled", "tile_size", "tile_stride"), + onload_model_names=("vae_encoder",) + ) + + def apply_controlnet_mask_on_latents(self, pipe, latents, mask): + mask = (pipe.preprocess_image(mask) + 1) / 2 + mask = mask.mean(dim=1, keepdim=True) + mask = 1 - torch.nn.functional.interpolate(mask, size=latents.shape[-2:]) + latents = torch.concat([latents, mask], dim=1) + return latents + + def apply_controlnet_mask_on_image(self, pipe, image, mask): + mask = mask.resize(image.size) + mask = pipe.preprocess_image(mask).mean(dim=[0, 1]).cpu() + image = np.array(image) + image[mask > 0] = 0 + image = Image.fromarray(image) + return image + + def process(self, pipe: FluxImagePipeline, controlnet_inputs: list[ControlNetInput], tiled, tile_size, tile_stride): + if controlnet_inputs is None: + return {} + pipe.load_models_to_device(['vae_encoder']) + conditionings = [] + for controlnet_input in controlnet_inputs: + image = controlnet_input.image + if controlnet_input.inpaint_mask is not None: + image = self.apply_controlnet_mask_on_image(pipe, image, controlnet_input.inpaint_mask) + + image = pipe.preprocess_image(image).to(device=pipe.device, dtype=pipe.torch_dtype) + image = pipe.vae_encoder(image, tiled=tiled, tile_size=tile_size, tile_stride=tile_stride) + + if controlnet_input.inpaint_mask is not None: + image = self.apply_controlnet_mask_on_latents(pipe, image, controlnet_input.inpaint_mask) + conditionings.append(image) + return {"controlnet_conditionings": conditionings} + + + class FluxImageUnit_IPAdapter(PipelineUnit): def __init__(self): super().__init__( @@ -325,6 +426,7 @@ class FluxImageUnit_IPAdapter(PipelineUnit): return inputs_shared, inputs_posi, inputs_nega + class FluxImageUnit_EntityControl(PipelineUnit): def __init__(self): super().__init__( @@ -428,7 +530,8 @@ def model_fn_flux_image( guidance=None, text_ids=None, image_ids=None, - controlnet_frames=None, + controlnet_inputs=None, + controlnet_conditionings=None, tiled=False, tile_size=128, tile_stride=64, @@ -444,11 +547,13 @@ def model_fn_flux_image( step1x_mask=None, step1x_reference_latents=None, tea_cache: TeaCache = None, + progress_id=0, + num_inference_steps=1, **kwargs ): if tiled: def flux_forward_fn(hl, hr, wl, wr): - tiled_controlnet_frames = [f[:, :, hl: hr, wl: wr] for f in controlnet_frames] if controlnet_frames is not None else None + tiled_controlnet_conditionings = [f[:, :, hl: hr, wl: wr] for f in controlnet_conditionings] if controlnet_conditionings is not None else None return model_fn_flux_image( dit=dit, controlnet=controlnet, @@ -459,7 +564,8 @@ def model_fn_flux_image( guidance=guidance, text_ids=text_ids, image_ids=None, - controlnet_frames=tiled_controlnet_frames, + controlnet_inputs=controlnet_inputs, + controlnet_conditionings=tiled_controlnet_conditionings, tiled=False, **kwargs ) @@ -475,7 +581,7 @@ def model_fn_flux_image( hidden_states = latents # ControlNet - if controlnet is not None and controlnet_frames is not None: + if controlnet is not None and controlnet_conditionings is not None: controlnet_extra_kwargs = { "hidden_states": hidden_states, "timestep": timestep, @@ -484,15 +590,18 @@ def model_fn_flux_image( "guidance": guidance, "text_ids": text_ids, "image_ids": image_ids, + "controlnet_inputs": controlnet_inputs, "tiled": tiled, "tile_size": tile_size, "tile_stride": tile_stride, + "progress_id": progress_id, + "num_inference_steps": num_inference_steps, } if id_emb is not None: controlnet_text_ids = torch.zeros(id_emb.shape[0], id_emb.shape[1], 3).to(device=hidden_states.device, dtype=hidden_states.dtype) controlnet_extra_kwargs.update({"prompt_emb": id_emb, 'text_ids': controlnet_text_ids, 'guidance': infinityou_guidance}) controlnet_res_stack, controlnet_single_res_stack = controlnet( - controlnet_frames, **controlnet_extra_kwargs + controlnet_conditionings, **controlnet_extra_kwargs ) # Flex @@ -554,7 +663,7 @@ def model_fn_flux_image( ipadapter_kwargs_list=ipadapter_kwargs_list.get(block_id, None) ) # ControlNet - if controlnet is not None and controlnet_frames is not None: + if controlnet is not None and controlnet_conditionings is not None and controlnet_res_stack is not None: hidden_states = hidden_states + controlnet_res_stack[block_id] # Single Blocks @@ -570,7 +679,7 @@ def model_fn_flux_image( ipadapter_kwargs_list=ipadapter_kwargs_list.get(block_id + num_joint_blocks, None) ) # ControlNet - if controlnet is not None and controlnet_frames is not None: + if controlnet is not None and controlnet_conditionings is not None and controlnet_single_res_stack is not None: hidden_states[:, prompt_emb.shape[1]:] = hidden_states[:, prompt_emb.shape[1]:] + controlnet_single_res_stack[block_id] hidden_states = hidden_states[:, prompt_emb.shape[1]:] diff --git a/examples/flux/FLUX.1-dev-Controlnet-Inpainting-Beta.py b/examples/flux/FLUX.1-dev-Controlnet-Inpainting-Beta.py new file mode 100644 index 0000000..f003cc9 --- /dev/null +++ b/examples/flux/FLUX.1-dev-Controlnet-Inpainting-Beta.py @@ -0,0 +1,37 @@ +import torch +from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig, ControlNetInput +import numpy as np +from PIL import Image + + +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), + ModelConfig(model_id="alimama-creative/FLUX.1-dev-Controlnet-Inpainting-Beta", origin_file_pattern="diffusion_pytorch_model.safetensors"), + ], +) + +image_1 = pipe( + prompt="a cat sitting on a chair", + height=1024, width=1024, + seed=8, rand_device="cuda", +) +image_1.save("image_1.jpg") + +mask = np.zeros((1024, 1024, 3), dtype=np.uint8) +mask[100:350, 350: -300] = 255 +mask = Image.fromarray(mask) +mask.save("mask.jpg") + +image_2 = pipe( + prompt="a cat sitting on a chair, wearing sunglasses", + controlnet_inputs=[ControlNetInput(image=image_1, inpaint_mask=mask, scale=0.9)], + height=1024, width=1024, + seed=9, rand_device="cuda", +) +image_2.save("image_2.jpg") \ No newline at end of file diff --git a/examples/flux/FLUX.1-dev-Controlnet-Union-alpha.py b/examples/flux/FLUX.1-dev-Controlnet-Union-alpha.py new file mode 100644 index 0000000..4164cc7 --- /dev/null +++ b/examples/flux/FLUX.1-dev-Controlnet-Union-alpha.py @@ -0,0 +1,40 @@ +import torch +from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig, ControlNetInput +from diffsynth.controlnets.processors import Annotator +from diffsynth import download_models + + + +download_models(["Annotators:Depth"]) +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), + ModelConfig(model_id="InstantX/FLUX.1-dev-Controlnet-Union-alpha", origin_file_pattern="diffusion_pytorch_model.safetensors"), + ], +) + +image_1 = pipe( + prompt="a beautiful Asian girl, full body, red dress, summer", + height=1024, width=1024, + seed=6, rand_device="cuda", +) +image_1.save("image_1.jpg") + +image_canny = Annotator("canny")(image_1) +image_depth = Annotator("depth")(image_1) + +image_2 = pipe( + prompt="a beautiful Asian girl, full body, red dress, winter", + controlnet_inputs=[ + ControlNetInput(image=image_canny, scale=0.3, processor_id="canny"), + ControlNetInput(image=image_depth, scale=0.3, processor_id="depth"), + ], + height=1024, width=1024, + seed=7, rand_device="cuda", +) +image_2.save("image_2.jpg") diff --git a/examples/flux/FLUX.1-dev-Controlnet-Upscaler.py b/examples/flux/FLUX.1-dev-Controlnet-Upscaler.py new file mode 100644 index 0000000..2bd47d0 --- /dev/null +++ b/examples/flux/FLUX.1-dev-Controlnet-Upscaler.py @@ -0,0 +1,33 @@ +import torch +from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig, ControlNetInput + + +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), + ModelConfig(model_id="jasperai/Flux.1-dev-Controlnet-Upscaler", origin_file_pattern="diffusion_pytorch_model.safetensors"), + ], +) + +image_1 = pipe( + prompt="a photo of a cat, highly detailed", + height=768, width=768, + seed=0, rand_device="cuda", +) +image_1.save("image_1.jpg") + +image_1 = image_1.resize((2048, 2048)) +image_2 = pipe( + prompt="a photo of a cat, highly detailed", + controlnet_inputs=[ControlNetInput(image=image_1, scale=0.7)], + input_image=image_1, + denoising_strength=0.99, + height=2048, width=2048, tiled=True, + seed=1, rand_device="cuda", +) +image_2.save("image_2.jpg") \ No newline at end of file diff --git a/examples/flux/FLUX.1-dev.py b/examples/flux/FLUX.1-dev.py index 6355436..d154460 100644 --- a/examples/flux/FLUX.1-dev.py +++ b/examples/flux/FLUX.1-dev.py @@ -1,8 +1,5 @@ import torch -from PIL import Image -from diffsynth import save_video, VideoData from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig -from modelscope import dataset_snapshot_download pipe = FluxImagePipeline.from_pretrained( @@ -16,8 +13,14 @@ pipe = FluxImagePipeline.from_pretrained( ], ) +prompt = "CG, masterpiece, best quality, solo, long hair, wavy hair, silver hair, blue eyes, blue dress, medium breasts, dress, underwater, air bubble, floating hair, refraction, portrait. The girl's flowing silver hair shimmers with every color of the rainbow and cascades down, merging with the floating flora around her." +negative_prompt = "worst quality, low quality, monochrome, zombie, interlocked fingers, Aissist, cleavage, nsfw," + +image = pipe(prompt=prompt, seed=0) +image.save("flux.jpg") + image = pipe( - prompt="a girl", - seed=0, + prompt=prompt, negative_prompt=negative_prompt, + seed=0, cfg_scale=2, num_inference_steps=50, ) -image.save("0.jpg") \ No newline at end of file +image.save("flux_cfg.jpg") From c8ad643374c95f23608c70f1f3373e869f5ac580 Mon Sep 17 00:00:00 2001 From: Artiprocher Date: Tue, 24 Jun 2025 19:17:43 +0800 Subject: [PATCH 07/14] refine examples --- diffsynth/pipelines/wan_video_new.py | 8 ++++++-- .../flux/{flux_entity_control.py => EliGen.py} | 0 ...ux_ipadapter.py => FLUX.1-dev-IP-Adapter.py} | 13 ++++--------- ...{flux_teacache.py => FLUX.1-dev-TeaCache.py} | 0 ...{flex_text_to_image.py => Flex.2-preview.py} | 0 examples/flux/{step1x.py => Step1X-Edit.py} | 16 ++-------------- image_1.jpg | Bin 0 -> 74535 bytes image_2.jpg | Bin 0 -> 69380 bytes 8 files changed, 12 insertions(+), 25 deletions(-) rename examples/flux/{flux_entity_control.py => EliGen.py} (100%) rename examples/flux/{flux_ipadapter.py => FLUX.1-dev-IP-Adapter.py} (72%) rename examples/flux/{flux_teacache.py => FLUX.1-dev-TeaCache.py} (100%) rename examples/flux/{flex_text_to_image.py => Flex.2-preview.py} (100%) rename examples/flux/{step1x.py => Step1X-Edit.py} (77%) create mode 100644 image_1.jpg create mode 100644 image_2.jpg diff --git a/diffsynth/pipelines/wan_video_new.py b/diffsynth/pipelines/wan_video_new.py index a93694c..a9d9ad1 100644 --- a/diffsynth/pipelines/wan_video_new.py +++ b/diffsynth/pipelines/wan_video_new.py @@ -169,7 +169,7 @@ class ModelConfig: def download_if_necessary(self, local_model_path="./models", skip_download=False, use_usp=False): if self.path is None: # Check model_id and origin_file_pattern - if self.model_id is None or self.origin_file_pattern is None: + if self.model_id is None: raise ValueError(f"""No valid model files. Please use `ModelConfig(path="xxx")` or `ModelConfig(model_id="xxx/yyy", origin_file_pattern="zzz")`.""") # Skip if not in rank 0 @@ -178,7 +178,11 @@ class ModelConfig: skip_download = dist.get_rank() != 0 # Check whether the origin path is a folder - if isinstance(self.origin_file_pattern, str) and self.origin_file_pattern.endswith("/"): + if self.origin_file_pattern is None: + self.origin_file_pattern = "" + allow_file_pattern = None + is_folder = True + elif isinstance(self.origin_file_pattern, str) and self.origin_file_pattern.endswith("/"): allow_file_pattern = self.origin_file_pattern + "*" is_folder = True else: diff --git a/examples/flux/flux_entity_control.py b/examples/flux/EliGen.py similarity index 100% rename from examples/flux/flux_entity_control.py rename to examples/flux/EliGen.py diff --git a/examples/flux/flux_ipadapter.py b/examples/flux/FLUX.1-dev-IP-Adapter.py similarity index 72% rename from examples/flux/flux_ipadapter.py rename to examples/flux/FLUX.1-dev-IP-Adapter.py index 6214e4d..e70301f 100644 --- a/examples/flux/flux_ipadapter.py +++ b/examples/flux/FLUX.1-dev-IP-Adapter.py @@ -1,10 +1,7 @@ import torch -from PIL import Image -from diffsynth import save_video, VideoData, download_models from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig -from modelscope import dataset_snapshot_download -#TODO: repalce the local path with model_id + pipe = FluxImagePipeline.from_pretrained( torch_dtype=torch.bfloat16, device="cuda", @@ -14,16 +11,14 @@ pipe = FluxImagePipeline.from_pretrained( ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), ModelConfig(model_id="InstantX/FLUX.1-dev-IP-Adapter", origin_file_pattern="ip-adapter.bin"), - ModelConfig(path="models/IpAdapter/InstantX/FLUX.1-dev-IP-Adapter/image_encoder") + ModelConfig(model_id="google/siglip-so400m-patch14-384"), ], ) -seed = 42 origin_prompt = "a rabbit in a garden, colorful flowers" -image = pipe(prompt=origin_prompt, height=1280, width=960, seed=seed) +image = pipe(prompt=origin_prompt, height=1280, width=960, seed=42) image.save("style image.jpg") -torch.manual_seed(seed) -image = pipe(prompt="A piggy", height=1280, width=960, seed=seed, +image = pipe(prompt="A piggy", height=1280, width=960, seed=42, ipadapter_images=[image], ipadapter_scale=0.7) image.save("A piggy.jpg") diff --git a/examples/flux/flux_teacache.py b/examples/flux/FLUX.1-dev-TeaCache.py similarity index 100% rename from examples/flux/flux_teacache.py rename to examples/flux/FLUX.1-dev-TeaCache.py diff --git a/examples/flux/flex_text_to_image.py b/examples/flux/Flex.2-preview.py similarity index 100% rename from examples/flux/flex_text_to_image.py rename to examples/flux/Flex.2-preview.py diff --git a/examples/flux/step1x.py b/examples/flux/Step1X-Edit.py similarity index 77% rename from examples/flux/step1x.py rename to examples/flux/Step1X-Edit.py index eca7605..33ee80d 100644 --- a/examples/flux/step1x.py +++ b/examples/flux/Step1X-Edit.py @@ -1,13 +1,9 @@ import torch from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig -from modelscope import snapshot_download from PIL import Image import numpy as np -snapshot_download("Qwen/Qwen2.5-VL-7B-Instruct", cache_dir="./models") -snapshot_download("stepfun-ai/Step1X-Edit", cache_dir="./models") - pipe = FluxImagePipeline.from_pretrained( torch_dtype=torch.bfloat16, device="cuda", @@ -18,27 +14,19 @@ pipe = FluxImagePipeline.from_pretrained( ], ) - -pipe.enable_vram_management() - image = Image.fromarray(np.zeros((1248, 832, 3), dtype=np.uint8) + 255) image = pipe( prompt="draw red flowers in Chinese ink painting style", step1x_reference_image=image, width=832, height=1248, cfg_scale=6, - seed=1, - rand_device='cuda' + seed=1, rand_device='cuda' ) image.save("image_1.jpg") - - image = pipe( prompt="add more flowers in Chinese ink painting style", step1x_reference_image=image, width=832, height=1248, cfg_scale=6, - seed=2, - rand_device='cuda' + seed=2, rand_device='cuda' ) image.save("image_2.jpg") - diff --git a/image_1.jpg b/image_1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3b17e7aae43ae0cdce9248e94f5ce0a5c0d686a9 GIT binary patch literal 74535 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 literal 0 HcmV?d00001 diff --git a/image_2.jpg b/image_2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..03e645cde672758ed9dbda66da446b3accf98a54 GIT binary patch literal 69380 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 TG#AhU1ze3mm|R1=zdrmQQXAxf literal 0 HcmV?d00001 From 8072d3839d564d7c45e153c5e6cdf9d183837db1 Mon Sep 17 00:00:00 2001 From: Artiprocher Date: Tue, 24 Jun 2025 19:17:54 +0800 Subject: [PATCH 08/14] refine examples --- image_1.jpg | Bin 74535 -> 0 bytes image_2.jpg | Bin 69380 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 image_1.jpg delete mode 100644 image_2.jpg diff --git a/image_1.jpg b/image_1.jpg deleted file mode 100644 index 3b17e7aae43ae0cdce9248e94f5ce0a5c0d686a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74535 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 diff --git a/image_2.jpg b/image_2.jpg deleted file mode 100644 index 03e645cde672758ed9dbda66da446b3accf98a54..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 69380 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 TG#AhU1ze3mm|R1=zdrmQQXAxf From 6c8bb6438b8b3ebbaea8de1dafa09c27b6a06ab2 Mon Sep 17 00:00:00 2001 From: Artiprocher Date: Wed, 25 Jun 2025 10:33:11 +0800 Subject: [PATCH 09/14] infiniteyou --- diffsynth/pipelines/flux_image_new.py | 76 +++++++++++++++++++++++++ examples/flux/FLUX.1-dev-InfiniteYou.py | 52 +++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 examples/flux/FLUX.1-dev-InfiniteYou.py diff --git a/diffsynth/pipelines/flux_image_new.py b/diffsynth/pipelines/flux_image_new.py index 68f65a1..5dd553a 100644 --- a/diffsynth/pipelines/flux_image_new.py +++ b/diffsynth/pipelines/flux_image_new.py @@ -97,6 +97,7 @@ class FluxImagePipeline(BasePipeline): FluxImageUnit_InputImageEmbedder(), FluxImageUnit_ImageIDs(), FluxImageUnit_EmbeddedGuidanceEmbedder(), + FluxImageUnit_InfiniteYou(), FluxImageUnit_ControlNet(), FluxImageUnit_IPAdapter(), FluxImageUnit_EntityControl(), @@ -165,6 +166,10 @@ class FluxImagePipeline(BasePipeline): pipe.qwenvl = model_manager.fetch_model("qwenvl") pipe.step1x_connector = model_manager.fetch_model("step1x_connector") + pipe.image_proj_model = model_manager.fetch_model("infiniteyou_image_projector") + if pipe.image_proj_model is not None: + pipe.infinityou_processor = InfinitYou(device=device) + # ControlNet controlnets = [] for model_name, model in zip(model_manager.model_name, model_manager.model): @@ -551,6 +556,77 @@ class FluxImageUnit_Flex(PipelineUnit): return {} + +class FluxImageUnit_InfiniteYou(PipelineUnit): + def __init__(self): + super().__init__( + input_params=("controlnet_inputs", "infinityou_id_image", "infinityou_guidance", "height", "width"), + ) + + def process(self, pipe: FluxImagePipeline, controlnet_inputs: list[ControlNetInput], infinityou_id_image, infinityou_guidance, height, width): + if infinityou_id_image is not None: + output = pipe.infinityou_processor.prepare_infinite_you(pipe.image_proj_model, infinityou_id_image, controlnet_inputs, infinityou_guidance, height, width) + infinityou_kwargs, controlnet_image = output[0], output[1] + if controlnet_inputs is None and isinstance(controlnet_image, Image.Image): + infinityou_kwargs["controlnet_inputs"] = [ControlNetInput(image=controlnet_image, scale=1.0, processor_id="None")] + return infinityou_kwargs + else: + return {} + + + +class InfinitYou: + def __init__(self, device="cuda", torch_dtype=torch.bfloat16): + from facexlib.recognition import init_recognition_model + from insightface.app import FaceAnalysis + self.device = device + self.torch_dtype = torch_dtype + # insightface_root_path = 'models/InfiniteYou/insightface' + insightface_root_path = 'models/ByteDance/InfiniteYou/supports/insightface' + self.app_640 = FaceAnalysis(name='antelopev2', root=insightface_root_path, providers=['CUDAExecutionProvider', 'CPUExecutionProvider']) + self.app_640.prepare(ctx_id=0, det_size=(640, 640)) + self.app_320 = FaceAnalysis(name='antelopev2', root=insightface_root_path, providers=['CUDAExecutionProvider', 'CPUExecutionProvider']) + self.app_320.prepare(ctx_id=0, det_size=(320, 320)) + self.app_160 = FaceAnalysis(name='antelopev2', root=insightface_root_path, providers=['CUDAExecutionProvider', 'CPUExecutionProvider']) + self.app_160.prepare(ctx_id=0, det_size=(160, 160)) + self.arcface_model = init_recognition_model('arcface', device=self.device) + + def _detect_face(self, id_image_cv2): + face_info = self.app_640.get(id_image_cv2) + if len(face_info) > 0: + return face_info + face_info = self.app_320.get(id_image_cv2) + if len(face_info) > 0: + return face_info + face_info = self.app_160.get(id_image_cv2) + return face_info + + def extract_arcface_bgr_embedding(self, in_image, landmark): + from insightface.utils import face_align + arc_face_image = face_align.norm_crop(in_image, landmark=np.array(landmark), image_size=112) + arc_face_image = torch.from_numpy(arc_face_image).unsqueeze(0).permute(0, 3, 1, 2) / 255. + arc_face_image = 2 * arc_face_image - 1 + arc_face_image = arc_face_image.contiguous().to(self.device) + face_emb = self.arcface_model(arc_face_image)[0] # [512], normalized + return face_emb + + def prepare_infinite_you(self, model, id_image, controlnet_image, infinityou_guidance, height, width): + import cv2 + if id_image is None: + return {'id_emb': None}, controlnet_image + id_image_cv2 = cv2.cvtColor(np.array(id_image), cv2.COLOR_RGB2BGR) + face_info = self._detect_face(id_image_cv2) + if len(face_info) == 0: + raise ValueError('No face detected in the input ID image') + landmark = sorted(face_info, key=lambda x:(x['bbox'][2]-x['bbox'][0])*(x['bbox'][3]-x['bbox'][1]))[-1]['kps'] # only use the maximum face + id_emb = self.extract_arcface_bgr_embedding(id_image_cv2, landmark) + id_emb = model(id_emb.unsqueeze(0).reshape([1, -1, 512]).to(dtype=self.torch_dtype)) + if controlnet_image is None: + controlnet_image = Image.fromarray(np.zeros([height, width, 3]).astype(np.uint8)) + infinityou_guidance = torch.Tensor([infinityou_guidance]).to(device=self.device, dtype=self.torch_dtype) + return {'id_emb': id_emb, 'infinityou_guidance': infinityou_guidance}, controlnet_image + + class TeaCache: def __init__(self, num_inference_steps, rel_l1_thresh): self.num_inference_steps = num_inference_steps diff --git a/examples/flux/FLUX.1-dev-InfiniteYou.py b/examples/flux/FLUX.1-dev-InfiniteYou.py new file mode 100644 index 0000000..9f39816 --- /dev/null +++ b/examples/flux/FLUX.1-dev-InfiniteYou.py @@ -0,0 +1,52 @@ +import torch +from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig, ControlNetInput +from modelscope import dataset_snapshot_download +from modelscope import snapshot_download +from PIL import Image + + +snapshot_download( + "ByteDance/InfiniteYou", + allow_file_pattern="supports/insightface/models/antelopev2/*", + local_dir="models/ByteDance/InfiniteYou", +) +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), + ModelConfig(model_id="ByteDance/InfiniteYou", origin_file_pattern="infu_flux_v1.0/aes_stage2/image_proj_model.bin"), + ModelConfig(model_id="ByteDance/InfiniteYou", origin_file_pattern="infu_flux_v1.0/aes_stage2/InfuseNetModel/*.safetensors"), + ], +) + +dataset_snapshot_download( + dataset_id="DiffSynth-Studio/examples_in_diffsynth", + local_dir="./", + allow_file_pattern=f"data/examples/infiniteyou/*", +) + +prompt = "A man, portrait, cinematic" +id_image = "data/examples/infiniteyou/man.jpg" +id_image = Image.open(id_image).convert('RGB') +image = pipe( + prompt=prompt, seed=1, + infinityou_id_image=id_image, infinityou_guidance=1.0, + num_inference_steps=50, embedded_guidance=3.5, + height=1024, width=1024, +) +image.save("man.jpg") + +prompt = "A woman, portrait, cinematic" +id_image = "data/examples/infiniteyou/woman.jpg" +id_image = Image.open(id_image).convert('RGB') +image = pipe( + prompt=prompt, seed=1, + infinityou_id_image=id_image, infinityou_guidance=1.0, + num_inference_steps=50, embedded_guidance=3.5, + height=1024, width=1024, +) +image.save("woman.jpg") \ No newline at end of file From b603acd36a1c425731650900f3f55053b3d627f5 Mon Sep 17 00:00:00 2001 From: Artiprocher Date: Wed, 25 Jun 2025 13:38:21 +0800 Subject: [PATCH 10/14] refine examples --- examples/flux/{ => model_inference}/EliGen.py | 0 .../FLUX.1-dev-Controlnet-Inpainting-Beta.py | 0 .../{ => model_inference}/FLUX.1-dev-Controlnet-Union-alpha.py | 0 .../flux/{ => model_inference}/FLUX.1-dev-Controlnet-Upscaler.py | 0 examples/flux/{ => model_inference}/FLUX.1-dev-IP-Adapter.py | 0 examples/flux/{ => model_inference}/FLUX.1-dev-InfiniteYou.py | 0 examples/flux/{ => model_inference}/FLUX.1-dev-TeaCache.py | 0 examples/flux/{ => model_inference}/FLUX.1-dev.py | 0 examples/flux/{ => model_inference}/Flex.2-preview.py | 0 examples/flux/{ => model_inference}/Step1X-Edit.py | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename examples/flux/{ => model_inference}/EliGen.py (100%) rename examples/flux/{ => model_inference}/FLUX.1-dev-Controlnet-Inpainting-Beta.py (100%) rename examples/flux/{ => model_inference}/FLUX.1-dev-Controlnet-Union-alpha.py (100%) rename examples/flux/{ => model_inference}/FLUX.1-dev-Controlnet-Upscaler.py (100%) rename examples/flux/{ => model_inference}/FLUX.1-dev-IP-Adapter.py (100%) rename examples/flux/{ => model_inference}/FLUX.1-dev-InfiniteYou.py (100%) rename examples/flux/{ => model_inference}/FLUX.1-dev-TeaCache.py (100%) rename examples/flux/{ => model_inference}/FLUX.1-dev.py (100%) rename examples/flux/{ => model_inference}/Flex.2-preview.py (100%) rename examples/flux/{ => model_inference}/Step1X-Edit.py (100%) diff --git a/examples/flux/EliGen.py b/examples/flux/model_inference/EliGen.py similarity index 100% rename from examples/flux/EliGen.py rename to examples/flux/model_inference/EliGen.py diff --git a/examples/flux/FLUX.1-dev-Controlnet-Inpainting-Beta.py b/examples/flux/model_inference/FLUX.1-dev-Controlnet-Inpainting-Beta.py similarity index 100% rename from examples/flux/FLUX.1-dev-Controlnet-Inpainting-Beta.py rename to examples/flux/model_inference/FLUX.1-dev-Controlnet-Inpainting-Beta.py diff --git a/examples/flux/FLUX.1-dev-Controlnet-Union-alpha.py b/examples/flux/model_inference/FLUX.1-dev-Controlnet-Union-alpha.py similarity index 100% rename from examples/flux/FLUX.1-dev-Controlnet-Union-alpha.py rename to examples/flux/model_inference/FLUX.1-dev-Controlnet-Union-alpha.py diff --git a/examples/flux/FLUX.1-dev-Controlnet-Upscaler.py b/examples/flux/model_inference/FLUX.1-dev-Controlnet-Upscaler.py similarity index 100% rename from examples/flux/FLUX.1-dev-Controlnet-Upscaler.py rename to examples/flux/model_inference/FLUX.1-dev-Controlnet-Upscaler.py diff --git a/examples/flux/FLUX.1-dev-IP-Adapter.py b/examples/flux/model_inference/FLUX.1-dev-IP-Adapter.py similarity index 100% rename from examples/flux/FLUX.1-dev-IP-Adapter.py rename to examples/flux/model_inference/FLUX.1-dev-IP-Adapter.py diff --git a/examples/flux/FLUX.1-dev-InfiniteYou.py b/examples/flux/model_inference/FLUX.1-dev-InfiniteYou.py similarity index 100% rename from examples/flux/FLUX.1-dev-InfiniteYou.py rename to examples/flux/model_inference/FLUX.1-dev-InfiniteYou.py diff --git a/examples/flux/FLUX.1-dev-TeaCache.py b/examples/flux/model_inference/FLUX.1-dev-TeaCache.py similarity index 100% rename from examples/flux/FLUX.1-dev-TeaCache.py rename to examples/flux/model_inference/FLUX.1-dev-TeaCache.py diff --git a/examples/flux/FLUX.1-dev.py b/examples/flux/model_inference/FLUX.1-dev.py similarity index 100% rename from examples/flux/FLUX.1-dev.py rename to examples/flux/model_inference/FLUX.1-dev.py diff --git a/examples/flux/Flex.2-preview.py b/examples/flux/model_inference/Flex.2-preview.py similarity index 100% rename from examples/flux/Flex.2-preview.py rename to examples/flux/model_inference/Flex.2-preview.py diff --git a/examples/flux/Step1X-Edit.py b/examples/flux/model_inference/Step1X-Edit.py similarity index 100% rename from examples/flux/Step1X-Edit.py rename to examples/flux/model_inference/Step1X-Edit.py From fcf2fbc07fd235c3b7b9465108aca14165a260d4 Mon Sep 17 00:00:00 2001 From: Artiprocher Date: Fri, 27 Jun 2025 10:20:11 +0800 Subject: [PATCH 11/14] flux-refactor --- diffsynth/pipelines/flux_image_new.py | 25 ++- diffsynth/pipelines/wan_video_new.py | 2 +- diffsynth/trainers/utils.py | 152 +++++++++++++++++- diffsynth/vram_management/__init__.py | 1 + .../vram_management/gradient_checkpointing.py | 34 ++++ download.py | 3 + .../{Flex.2-preview.py => FLEX.2-preview.py} | 0 .../full/FLUX.1-dev-IP-Adapter.sh | 14 ++ .../flux/model_training/full/FLUX.1-dev.sh | 12 ++ .../full/accelerate_config.yaml | 22 +++ .../flux/model_training/lora/FLUX.1-dev.sh | 15 ++ examples/flux/model_training/train.py | 117 ++++++++++++++ .../validate_full/FLUX.1-dev-IP-Adapter.py | 28 ++++ .../validate_full/FLUX.1-dev.py | 20 +++ .../validate_lora/FLUX.1-dev.py | 18 +++ 15 files changed, 456 insertions(+), 7 deletions(-) create mode 100644 diffsynth/vram_management/gradient_checkpointing.py create mode 100644 download.py rename examples/flux/model_inference/{Flex.2-preview.py => FLEX.2-preview.py} (100%) create mode 100644 examples/flux/model_training/full/FLUX.1-dev-IP-Adapter.sh create mode 100644 examples/flux/model_training/full/FLUX.1-dev.sh create mode 100644 examples/flux/model_training/full/accelerate_config.yaml create mode 100644 examples/flux/model_training/lora/FLUX.1-dev.sh create mode 100644 examples/flux/model_training/train.py create mode 100644 examples/flux/model_training/validate_full/FLUX.1-dev-IP-Adapter.py create mode 100644 examples/flux/model_training/validate_full/FLUX.1-dev.py create mode 100644 examples/flux/model_training/validate_lora/FLUX.1-dev.py diff --git a/diffsynth/pipelines/flux_image_new.py b/diffsynth/pipelines/flux_image_new.py index 5dd553a..3bf971d 100644 --- a/diffsynth/pipelines/flux_image_new.py +++ b/diffsynth/pipelines/flux_image_new.py @@ -18,10 +18,13 @@ from ..models import ModelManager, load_state_dict, SD3TextEncoder1, FluxTextEnc from ..models.step1x_connector import Qwen2Connector from ..models.flux_controlnet import FluxControlNet from ..models.flux_ipadapter import FluxIpAdapter +from ..models.flux_infiniteyou import InfiniteYouImageProjector from ..models.tiler import FastTileWorker from .wan_video_new import BasePipeline, ModelConfig, PipelineUnitRunner, PipelineUnit from ..lora.flux_lora import FluxLoRALoader +from ..vram_management import gradient_checkpoint_forward + @dataclass @@ -89,6 +92,8 @@ class FluxImagePipeline(BasePipeline): self.unit_runner = PipelineUnitRunner() self.qwenvl = None self.step1x_connector: Qwen2Connector = None + self.infinityou_processor: InfinitYou = None + self.image_proj_model: InfiniteYouImageProjector = None self.in_iteration_models = ("dit", "step1x_connector", "controlnet") self.units = [ FluxImageUnit_ShapeChecker(), @@ -209,7 +214,7 @@ class FluxImagePipeline(BasePipeline): # ControlNet controlnet_inputs: list[ControlNetInput] = None, # IP-Adapter - ipadapter_images: list[Image.Image] = None, + ipadapter_images: Union[list[Image.Image], Image.Image] = None, ipadapter_scale: float = 1.0, # EliGen eligen_entity_prompts: list[str] = None, @@ -426,6 +431,8 @@ class FluxImageUnit_IPAdapter(PipelineUnit): ipadapter_images, ipadapter_scale = inputs_shared.get("ipadapter_images", None), inputs_shared.get("ipadapter_scale", 1.0) if ipadapter_images is None: return inputs_shared, inputs_posi, inputs_nega + if not isinstance(ipadapter_images, list): + ipadapter_images = [ipadapter_images] pipe.load_models_to_device(self.onload_model_names) images = [image.convert("RGB").resize((384, 384), resample=3) for image in ipadapter_images] @@ -700,6 +707,8 @@ def model_fn_flux_image( tea_cache: TeaCache = None, progress_id=0, num_inference_steps=1, + use_gradient_checkpointing=False, + use_gradient_checkpointing_offload=False, **kwargs ): if tiled: @@ -805,13 +814,16 @@ def model_fn_flux_image( else: # Joint Blocks for block_id, block in enumerate(dit.blocks): - hidden_states, prompt_emb = block( + hidden_states, prompt_emb = gradient_checkpoint_forward( + block, + use_gradient_checkpointing, + use_gradient_checkpointing_offload, hidden_states, prompt_emb, conditioning, image_rotary_emb, attention_mask, - ipadapter_kwargs_list=ipadapter_kwargs_list.get(block_id, None) + ipadapter_kwargs_list=ipadapter_kwargs_list.get(block_id, None), ) # ControlNet if controlnet is not None and controlnet_conditionings is not None and controlnet_res_stack is not None: @@ -821,13 +833,16 @@ def model_fn_flux_image( hidden_states = torch.cat([prompt_emb, hidden_states], dim=1) num_joint_blocks = len(dit.blocks) for block_id, block in enumerate(dit.single_blocks): - hidden_states, prompt_emb = block( + hidden_states, prompt_emb = gradient_checkpoint_forward( + block, + use_gradient_checkpointing, + use_gradient_checkpointing_offload, hidden_states, prompt_emb, conditioning, image_rotary_emb, attention_mask, - ipadapter_kwargs_list=ipadapter_kwargs_list.get(block_id + num_joint_blocks, None) + ipadapter_kwargs_list=ipadapter_kwargs_list.get(block_id + num_joint_blocks, None), ) # ControlNet if controlnet is not None and controlnet_conditionings is not None and controlnet_single_res_stack is not None: diff --git a/diffsynth/pipelines/wan_video_new.py b/diffsynth/pipelines/wan_video_new.py index a9d9ad1..14e564c 100644 --- a/diffsynth/pipelines/wan_video_new.py +++ b/diffsynth/pipelines/wan_video_new.py @@ -178,7 +178,7 @@ class ModelConfig: skip_download = dist.get_rank() != 0 # Check whether the origin path is a folder - if self.origin_file_pattern is None: + if self.origin_file_pattern is None or self.origin_file_pattern == "": self.origin_file_pattern = "" allow_file_pattern = None is_folder = True diff --git a/diffsynth/trainers/utils.py b/diffsynth/trainers/utils.py index d627dab..7af03e6 100644 --- a/diffsynth/trainers/utils.py +++ b/diffsynth/trainers/utils.py @@ -7,6 +7,127 @@ from accelerate import Accelerator +class ImageDataset(torch.utils.data.Dataset): + def __init__( + self, + base_path=None, metadata_path=None, + max_pixels=1920*1080, height=None, width=None, + height_division_factor=16, width_division_factor=16, + data_file_keys=("image",), + image_file_extension=("jpg", "jpeg", "png", "webp"), + repeat=1, + args=None, + ): + if args is not None: + base_path = args.dataset_base_path + metadata_path = args.dataset_metadata_path + height = args.height + width = args.width + max_pixels = args.max_pixels + data_file_keys = args.data_file_keys.split(",") + repeat = args.dataset_repeat + + self.base_path = base_path + self.max_pixels = max_pixels + self.height = height + self.width = width + self.height_division_factor = height_division_factor + self.width_division_factor = width_division_factor + self.data_file_keys = data_file_keys + self.image_file_extension = image_file_extension + self.repeat = repeat + + if height is not None and width is not None: + print("Height and width are fixed. Setting `dynamic_resolution` to False.") + self.dynamic_resolution = False + elif height is None and width is None: + print("Height and width are none. Setting `dynamic_resolution` to True.") + self.dynamic_resolution = True + + if metadata_path is None: + print("No metadata. Trying to generate it.") + metadata = self.generate_metadata(base_path) + print(f"{len(metadata)} lines in metadata.") + else: + metadata = pd.read_csv(metadata_path) + self.data = [metadata.iloc[i].to_dict() for i in range(len(metadata))] + + + def generate_metadata(self, folder): + image_list, prompt_list = [], [] + file_set = set(os.listdir(folder)) + for file_name in file_set: + if "." not in file_name: + continue + file_ext_name = file_name.split(".")[-1].lower() + file_base_name = file_name[:-len(file_ext_name)-1] + if file_ext_name not in self.image_file_extension: + continue + prompt_file_name = file_base_name + ".txt" + if prompt_file_name not in file_set: + continue + with open(os.path.join(folder, prompt_file_name), "r", encoding="utf-8") as f: + prompt = f.read().strip() + image_list.append(file_name) + prompt_list.append(prompt) + metadata = pd.DataFrame() + metadata["image"] = image_list + metadata["prompt"] = prompt_list + return metadata + + + def crop_and_resize(self, image, target_height, target_width): + width, height = image.size + scale = max(target_width / width, target_height / height) + image = torchvision.transforms.functional.resize( + image, + (round(height*scale), round(width*scale)), + interpolation=torchvision.transforms.InterpolationMode.BILINEAR + ) + image = torchvision.transforms.functional.center_crop(image, (target_height, target_width)) + return image + + + def get_height_width(self, image): + if self.dynamic_resolution: + width, height = image.size + if width * height > self.max_pixels: + scale = (width * height / self.max_pixels) ** 0.5 + height, width = int(height / scale), int(width / scale) + height = height // self.height_division_factor * self.height_division_factor + width = width // self.width_division_factor * self.width_division_factor + else: + height, width = self.height, self.width + return height, width + + + def load_image(self, file_path): + image = Image.open(file_path).convert("RGB") + image = self.crop_and_resize(image, *self.get_height_width(image)) + return image + + + def load_data(self, file_path): + return self.load_image(file_path) + + + def __getitem__(self, data_id): + data = self.data[data_id % len(self.data)].copy() + for key in self.data_file_keys: + if key in data: + path = os.path.join(self.base_path, data[key]) + data[key] = self.load_data(path) + if data[key] is None: + warnings.warn(f"cannot load file {data[key]}.") + return None + return data + + + def __len__(self): + return len(self.data) * self.repeat + + + class VideoDataset(torch.utils.data.Dataset): def __init__( self, @@ -218,9 +339,10 @@ class DiffusionTrainingModule(torch.nn.Module): class ModelLogger: - def __init__(self, output_path, remove_prefix_in_ckpt=None): + def __init__(self, output_path, remove_prefix_in_ckpt=None, state_dict_converter=lambda x:x): self.output_path = output_path self.remove_prefix_in_ckpt = remove_prefix_in_ckpt + self.state_dict_converter = state_dict_converter def on_step_end(self, loss): @@ -232,6 +354,7 @@ class ModelLogger: if accelerator.is_main_process: state_dict = accelerator.get_state_dict(model) state_dict = accelerator.unwrap_model(model).export_trainable_state_dict(state_dict, remove_prefix=self.remove_prefix_in_ckpt) + state_dict = self.state_dict_converter(state_dict) os.makedirs(self.output_path, exist_ok=True) path = os.path.join(self.output_path, f"epoch-{epoch_id}.safetensors") accelerator.save(state_dict, path, safe_serialization=True) @@ -302,3 +425,30 @@ def wan_parser(): parser.add_argument("--gradient_accumulation_steps", type=int, default=1, help="Gradient accumulation steps.") return parser + + +def flux_parser(): + parser = argparse.ArgumentParser(description="Simple example of a training script.") + parser.add_argument("--dataset_base_path", type=str, default="", required=True, help="Base path of the dataset.") + parser.add_argument("--dataset_metadata_path", type=str, default=None, help="Path to the metadata file of the dataset.") + parser.add_argument("--max_pixels", type=int, default=1024*1024, help="Maximum number of pixels per frame, used for dynamic resolution..") + parser.add_argument("--height", type=int, default=None, help="Height of images. Leave `height` and `width` empty to enable dynamic resolution.") + parser.add_argument("--width", type=int, default=None, help="Width of images. Leave `height` and `width` empty to enable dynamic resolution.") + parser.add_argument("--data_file_keys", type=str, default="image", help="Data file keys in the metadata. Comma-separated.") + parser.add_argument("--dataset_repeat", type=int, default=1, help="Number of times to repeat the dataset per epoch.") + parser.add_argument("--model_paths", type=str, default=None, help="Paths to load models. In JSON format.") + parser.add_argument("--model_id_with_origin_paths", type=str, default=None, help="Model ID with origin paths, e.g., Wan-AI/Wan2.1-T2V-1.3B:diffusion_pytorch_model*.safetensors. Comma-separated.") + parser.add_argument("--learning_rate", type=float, default=1e-4, help="Learning rate.") + parser.add_argument("--num_epochs", type=int, default=1, help="Number of epochs.") + parser.add_argument("--output_path", type=str, default="./models", help="Output save path.") + parser.add_argument("--remove_prefix_in_ckpt", type=str, default="pipe.dit.", help="Remove prefix in ckpt.") + parser.add_argument("--trainable_models", type=str, default=None, help="Models to train, e.g., dit, vae, text_encoder.") + parser.add_argument("--lora_base_model", type=str, default=None, help="Which model LoRA is added to.") + parser.add_argument("--lora_target_modules", type=str, default="q,k,v,o,ffn.0,ffn.2", help="Which layers LoRA is added to.") + parser.add_argument("--lora_rank", type=int, default=32, help="Rank of LoRA.") + parser.add_argument("--extra_inputs", default=None, help="Additional model inputs, comma-separated.") + parser.add_argument("--align_to_opensource_format", default=False, action="store_true", help="Whether to align the lora format to opensource format. Only for DiT's LoRA.") + parser.add_argument("--use_gradient_checkpointing", default=False, action="store_true", help="Whether to use gradient checkpointing.") + parser.add_argument("--use_gradient_checkpointing_offload", default=False, action="store_true", help="Whether to offload gradient checkpointing to CPU memory.") + parser.add_argument("--gradient_accumulation_steps", type=int, default=1, help="Gradient accumulation steps.") + return parser diff --git a/diffsynth/vram_management/__init__.py b/diffsynth/vram_management/__init__.py index 69a388d..5b07580 100644 --- a/diffsynth/vram_management/__init__.py +++ b/diffsynth/vram_management/__init__.py @@ -1 +1,2 @@ from .layers import * +from .gradient_checkpointing import * diff --git a/diffsynth/vram_management/gradient_checkpointing.py b/diffsynth/vram_management/gradient_checkpointing.py new file mode 100644 index 0000000..b356415 --- /dev/null +++ b/diffsynth/vram_management/gradient_checkpointing.py @@ -0,0 +1,34 @@ +import torch + + +def create_custom_forward(module): + def custom_forward(*inputs, **kwargs): + return module(*inputs, **kwargs) + return custom_forward + + +def gradient_checkpoint_forward( + model, + use_gradient_checkpointing, + use_gradient_checkpointing_offload, + *args, + **kwargs, +): + if use_gradient_checkpointing_offload: + with torch.autograd.graph.save_on_cpu(): + model_output = torch.utils.checkpoint.checkpoint( + create_custom_forward(model), + *args, + **kwargs, + use_reentrant=False, + ) + elif use_gradient_checkpointing: + model_output = torch.utils.checkpoint.checkpoint( + create_custom_forward(model), + *args, + **kwargs, + use_reentrant=False, + ) + else: + model_output = model(*args, **kwargs) + return model_output diff --git a/download.py b/download.py new file mode 100644 index 0000000..1404010 --- /dev/null +++ b/download.py @@ -0,0 +1,3 @@ +#模型下载 +from modelscope import snapshot_download +model_dir = snapshot_download('black-forest-labs/FLUX.1-Kontext-dev', cache_dir="models", ignore_file_pattern="transformer/*") \ No newline at end of file diff --git a/examples/flux/model_inference/Flex.2-preview.py b/examples/flux/model_inference/FLEX.2-preview.py similarity index 100% rename from examples/flux/model_inference/Flex.2-preview.py rename to examples/flux/model_inference/FLEX.2-preview.py diff --git a/examples/flux/model_training/full/FLUX.1-dev-IP-Adapter.sh b/examples/flux/model_training/full/FLUX.1-dev-IP-Adapter.sh new file mode 100644 index 0000000..43bc006 --- /dev/null +++ b/examples/flux/model_training/full/FLUX.1-dev-IP-Adapter.sh @@ -0,0 +1,14 @@ +accelerate launch examples/flux/model_training/train.py \ + --dataset_base_path data/example_image_dataset \ + --dataset_metadata_path data/example_image_dataset/metadata_ipadapter.csv \ + --data_file_keys "image,ipadapter_images" \ + --max_pixels 1048576 \ + --dataset_repeat 100 \ + --model_id_with_origin_paths "black-forest-labs/FLUX.1-dev:flux1-dev.safetensors,black-forest-labs/FLUX.1-dev:text_encoder/model.safetensors,black-forest-labs/FLUX.1-dev:text_encoder_2/,black-forest-labs/FLUX.1-dev:ae.safetensors,InstantX/FLUX.1-dev-IP-Adapter:ip-adapter.bin,google/siglip-so400m-patch14-384:" \ + --learning_rate 1e-5 \ + --num_epochs 1 \ + --remove_prefix_in_ckpt "pipe.ipadapter." \ + --output_path "./models/train/FLUX.1-dev-IP-Adapter_full" \ + --trainable_models "ipadapter" \ + --extra_inputs "ipadapter_images" \ + --use_gradient_checkpointing diff --git a/examples/flux/model_training/full/FLUX.1-dev.sh b/examples/flux/model_training/full/FLUX.1-dev.sh new file mode 100644 index 0000000..9254957 --- /dev/null +++ b/examples/flux/model_training/full/FLUX.1-dev.sh @@ -0,0 +1,12 @@ +accelerate launch --config_file examples/flux/model_training/full/accelerate_config.yaml examples/flux/model_training/train.py \ + --dataset_base_path data/example_image_dataset \ + --dataset_metadata_path data/example_image_dataset/metadata.csv \ + --max_pixels 1048576 \ + --dataset_repeat 400 \ + --model_id_with_origin_paths "black-forest-labs/FLUX.1-dev:flux1-dev.safetensors,black-forest-labs/FLUX.1-dev:text_encoder/model.safetensors,black-forest-labs/FLUX.1-dev:text_encoder_2/,black-forest-labs/FLUX.1-dev:ae.safetensors" \ + --learning_rate 1e-5 \ + --num_epochs 1 \ + --remove_prefix_in_ckpt "pipe.dit." \ + --output_path "./models/train/FLUX.1-dev_full" \ + --trainable_models "dit" \ + --use_gradient_checkpointing diff --git a/examples/flux/model_training/full/accelerate_config.yaml b/examples/flux/model_training/full/accelerate_config.yaml new file mode 100644 index 0000000..83280f7 --- /dev/null +++ b/examples/flux/model_training/full/accelerate_config.yaml @@ -0,0 +1,22 @@ +compute_environment: LOCAL_MACHINE +debug: false +deepspeed_config: + gradient_accumulation_steps: 1 + offload_optimizer_device: none + offload_param_device: none + zero3_init_flag: false + zero_stage: 2 +distributed_type: DEEPSPEED +downcast_bf16: 'no' +enable_cpu_affinity: false +machine_rank: 0 +main_training_function: main +mixed_precision: bf16 +num_machines: 1 +num_processes: 8 +rdzv_backend: static +same_network: true +tpu_env: [] +tpu_use_cluster: false +tpu_use_sudo: false +use_cpu: false diff --git a/examples/flux/model_training/lora/FLUX.1-dev.sh b/examples/flux/model_training/lora/FLUX.1-dev.sh new file mode 100644 index 0000000..4b207ef --- /dev/null +++ b/examples/flux/model_training/lora/FLUX.1-dev.sh @@ -0,0 +1,15 @@ +accelerate launch examples/flux/model_training/train.py \ + --dataset_base_path data/example_image_dataset \ + --dataset_metadata_path data/example_image_dataset/metadata.csv \ + --max_pixels 1048576 \ + --dataset_repeat 50 \ + --model_id_with_origin_paths "black-forest-labs/FLUX.1-dev:flux1-dev.safetensors,black-forest-labs/FLUX.1-dev:text_encoder/model.safetensors,black-forest-labs/FLUX.1-dev:text_encoder_2/,black-forest-labs/FLUX.1-dev:ae.safetensors" \ + --learning_rate 1e-4 \ + --num_epochs 5 \ + --remove_prefix_in_ckpt "pipe.dit." \ + --output_path "./models/train/FLUX.1-dev_lora" \ + --lora_base_model "dit" \ + --lora_target_modules "a_to_qkv,b_to_qkv,ff_a.0,ff_a.2,ff_b.0,ff_b.2,a_to_out,b_to_out,proj_out,norm.linear,norm1_a.linear,norm1_b.linear,to_qkv_mlp" \ + --lora_rank 32 \ + --align_to_opensource_format \ + --use_gradient_checkpointing diff --git a/examples/flux/model_training/train.py b/examples/flux/model_training/train.py new file mode 100644 index 0000000..6717c9e --- /dev/null +++ b/examples/flux/model_training/train.py @@ -0,0 +1,117 @@ +import torch, os, json +from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig +from diffsynth.trainers.utils import DiffusionTrainingModule, ImageDataset, ModelLogger, launch_training_task, flux_parser +from diffsynth.models.lora import FluxLoRAConverter +os.environ["TOKENIZERS_PARALLELISM"] = "false" + + + +class FluxTrainingModule(DiffusionTrainingModule): + def __init__( + self, + model_paths=None, model_id_with_origin_paths=None, + trainable_models=None, + lora_base_model=None, lora_target_modules="a_to_qkv,b_to_qkv,ff_a.0,ff_a.2,ff_b.0,ff_b.2,a_to_out,b_to_out,proj_out,norm.linear,norm1_a.linear,norm1_b.linear,to_qkv_mlp", lora_rank=32, + use_gradient_checkpointing=True, + use_gradient_checkpointing_offload=False, + extra_inputs=None, + ): + super().__init__() + # Load models + model_configs = [] + if model_paths is not None: + model_paths = json.loads(model_paths) + model_configs += [ModelConfig(path=path) for path in model_paths] + if model_id_with_origin_paths is not None: + model_id_with_origin_paths = model_id_with_origin_paths.split(",") + model_configs += [ModelConfig(model_id=i.split(":")[0], origin_file_pattern=i.split(":")[1]) for i in model_id_with_origin_paths] + self.pipe = FluxImagePipeline.from_pretrained(torch_dtype=torch.bfloat16, device="cpu", model_configs=model_configs) + + # Reset training scheduler + self.pipe.scheduler.set_timesteps(1000, training=True) + + # Freeze untrainable models + self.pipe.freeze_except([] if trainable_models is None else trainable_models.split(",")) + + # Add LoRA to the base models + if lora_base_model is not None: + model = self.add_lora_to_model( + getattr(self.pipe, lora_base_model), + target_modules=lora_target_modules.split(","), + lora_rank=lora_rank + ) + setattr(self.pipe, lora_base_model, model) + + # Store other configs + self.use_gradient_checkpointing = use_gradient_checkpointing + self.use_gradient_checkpointing_offload = use_gradient_checkpointing_offload + self.extra_inputs = extra_inputs.split(",") if extra_inputs is not None else [] + + + def forward_preprocess(self, data): + # CFG-sensitive parameters + inputs_posi = {"prompt": data["prompt"]} + inputs_nega = {} + + # CFG-unsensitive parameters + inputs_shared = { + # Assume you are using this pipeline for inference, + # please fill in the input parameters. + "input_image": data["image"], + "height": data["image"].size[1], + "width": data["image"].size[0], + # Please do not modify the following parameters + # unless you clearly know what this will cause. + "cfg_scale": 1, + "embedded_guidance": 1, + "t5_sequence_length": 512, + "tiled": False, + "rand_device": self.pipe.device, + "use_gradient_checkpointing": self.use_gradient_checkpointing, + "use_gradient_checkpointing_offload": self.use_gradient_checkpointing_offload, + } + + # Extra inputs + for extra_input in self.extra_inputs: + inputs_shared[extra_input] = data[extra_input] + + # Pipeline units will automatically process the input parameters. + for unit in self.pipe.units: + inputs_shared, inputs_posi, inputs_nega = self.pipe.unit_runner(unit, self.pipe, inputs_shared, inputs_posi, inputs_nega) + return {**inputs_shared, **inputs_posi} + + + def forward(self, data, inputs=None): + if inputs is None: inputs = self.forward_preprocess(data) + models = {name: getattr(self.pipe, name) for name in self.pipe.in_iteration_models} + loss = self.pipe.training_loss(**models, **inputs) + return loss + + + +if __name__ == "__main__": + parser = flux_parser() + args = parser.parse_args() + dataset = ImageDataset(args=args) + model = FluxTrainingModule( + model_paths=args.model_paths, + model_id_with_origin_paths=args.model_id_with_origin_paths, + trainable_models=args.trainable_models, + lora_base_model=args.lora_base_model, + lora_target_modules=args.lora_target_modules, + lora_rank=args.lora_rank, + use_gradient_checkpointing_offload=args.use_gradient_checkpointing_offload, + extra_inputs=args.extra_inputs, + ) + model_logger = ModelLogger( + args.output_path, + remove_prefix_in_ckpt=args.remove_prefix_in_ckpt, + state_dict_converter=FluxLoRAConverter.align_to_opensource_format if args.align_to_opensource_format else lambda x:x, + ) + optimizer = torch.optim.AdamW(model.trainable_modules(), lr=args.learning_rate) + scheduler = torch.optim.lr_scheduler.ConstantLR(optimizer) + launch_training_task( + dataset, model, model_logger, optimizer, scheduler, + num_epochs=args.num_epochs, + gradient_accumulation_steps=args.gradient_accumulation_steps, + ) diff --git a/examples/flux/model_training/validate_full/FLUX.1-dev-IP-Adapter.py b/examples/flux/model_training/validate_full/FLUX.1-dev-IP-Adapter.py new file mode 100644 index 0000000..b6bab3d --- /dev/null +++ b/examples/flux/model_training/validate_full/FLUX.1-dev-IP-Adapter.py @@ -0,0 +1,28 @@ +import torch +from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig +from diffsynth import load_state_dict +from PIL import Image + + +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), + ModelConfig(model_id="InstantX/FLUX.1-dev-IP-Adapter", origin_file_pattern="ip-adapter.bin"), + ModelConfig(model_id="google/siglip-so400m-patch14-384"), + ], +) +state_dict = load_state_dict("models/train/FLUX.1-dev-IP-Adapter_full/epoch-0.safetensors") +pipe.ipadapter.load_state_dict(state_dict) + +image = pipe( + prompt="a dog", + ipadapter_images=Image.open("data/example_image_dataset/1.jpg"), + height=768, width=768, + seed=0 +) +image.save("image_FLUX.1-dev-IP-Adapter_full.jpg") diff --git a/examples/flux/model_training/validate_full/FLUX.1-dev.py b/examples/flux/model_training/validate_full/FLUX.1-dev.py new file mode 100644 index 0000000..d3adf7a --- /dev/null +++ b/examples/flux/model_training/validate_full/FLUX.1-dev.py @@ -0,0 +1,20 @@ +import torch +from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig +from diffsynth import load_state_dict + + +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), + ], +) +state_dict = load_state_dict("models/train/FLUX.1-dev_full/epoch-0.safetensors") +pipe.dit.load_state_dict(state_dict) + +image = pipe(prompt="a dog", seed=0) +image.save("image_FLUX.1-dev_full.jpg") diff --git a/examples/flux/model_training/validate_lora/FLUX.1-dev.py b/examples/flux/model_training/validate_lora/FLUX.1-dev.py new file mode 100644 index 0000000..d1aebef --- /dev/null +++ b/examples/flux/model_training/validate_lora/FLUX.1-dev.py @@ -0,0 +1,18 @@ +import torch +from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig + + +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), + ], +) +pipe.load_lora(pipe.dit, "models/train/FLUX.1-dev_lora/epoch-4.safetensors", alpha=1) + +image = pipe(prompt="a dog", seed=0) +image.save("image_FLUX.1-dev_lora.jpg") From 009f26bb40b900c1c1b98e6660ce6b2450662b94 Mon Sep 17 00:00:00 2001 From: Artiprocher Date: Fri, 27 Jun 2025 18:38:40 +0800 Subject: [PATCH 12/14] kontext --- diffsynth/pipelines/flux_image_new.py | 51 +++++++++++++++++- download.py | 3 -- .../model_inference/FLUX.1-Kontext-dev.py | 54 +++++++++++++++++++ .../model_training/lora/FLUX.1-Kontext-dev.sh | 17 ++++++ .../validate_lora/FLUX.1-Kontext-dev.py | 24 +++++++++ 5 files changed, 144 insertions(+), 5 deletions(-) delete mode 100644 download.py create mode 100644 examples/flux/model_inference/FLUX.1-Kontext-dev.py create mode 100644 examples/flux/model_training/lora/FLUX.1-Kontext-dev.sh create mode 100644 examples/flux/model_training/validate_lora/FLUX.1-Kontext-dev.py diff --git a/diffsynth/pipelines/flux_image_new.py b/diffsynth/pipelines/flux_image_new.py index 3bf971d..1568efb 100644 --- a/diffsynth/pipelines/flux_image_new.py +++ b/diffsynth/pipelines/flux_image_new.py @@ -102,6 +102,7 @@ class FluxImagePipeline(BasePipeline): FluxImageUnit_InputImageEmbedder(), FluxImageUnit_ImageIDs(), FluxImageUnit_EmbeddedGuidanceEmbedder(), + FluxImageUnit_Kontext(), FluxImageUnit_InfiniteYou(), FluxImageUnit_ControlNet(), FluxImageUnit_IPAdapter(), @@ -211,6 +212,8 @@ class FluxImagePipeline(BasePipeline): multidiffusion_prompts=(), multidiffusion_masks=(), multidiffusion_scales=(), + # Kontext + kontext_images: Union[list[Image.Image], Image.Image] = None, # ControlNet controlnet_inputs: list[ControlNetInput] = None, # IP-Adapter @@ -257,6 +260,7 @@ class FluxImagePipeline(BasePipeline): "seed": seed, "rand_device": rand_device, "sigma_shift": sigma_shift, "num_inference_steps": num_inference_steps, "multidiffusion_prompts": multidiffusion_prompts, "multidiffusion_masks": multidiffusion_masks, "multidiffusion_scales": multidiffusion_scales, + "kontext_images": kontext_images, "controlnet_inputs": controlnet_inputs, "ipadapter_images": ipadapter_images, "ipadapter_scale": ipadapter_scale, "eligen_entity_prompts": eligen_entity_prompts, "eligen_entity_masks": eligen_entity_masks, "eligen_enable_on_negative": eligen_enable_on_negative, "eligen_enable_inpaint": eligen_enable_inpaint, @@ -378,6 +382,32 @@ class FluxImageUnit_EmbeddedGuidanceEmbedder(PipelineUnit): +class FluxImageUnit_Kontext(PipelineUnit): + def __init__(self): + super().__init__(input_params=("kontext_images", "tiled", "tile_size", "tile_stride")) + + def process(self, pipe: FluxImagePipeline, kontext_images, tiled, tile_size, tile_stride): + if kontext_images is None: + return {} + if not isinstance(kontext_images, list): + kontext_images = [kontext_images] + + kontext_latents = [] + kontext_image_ids = [] + for kontext_image in kontext_images: + kontext_image = pipe.preprocess_image(kontext_image) + kontext_latent = pipe.vae_encoder(kontext_image, tiled=tiled, tile_size=tile_size, tile_stride=tile_stride) + image_ids = pipe.dit.prepare_image_ids(kontext_latent) + image_ids[..., 0] = 1 + kontext_image_ids.append(image_ids) + kontext_latent = pipe.dit.patchify(kontext_latent) + kontext_latents.append(kontext_latent) + kontext_latents = torch.concat(kontext_latents, dim=1) + kontext_image_ids = torch.concat(kontext_image_ids, dim=-2) + return {"kontext_latents": kontext_latents, "kontext_image_ids": kontext_image_ids} + + + class FluxImageUnit_ControlNet(PipelineUnit): def __init__(self): super().__init__( @@ -688,6 +718,8 @@ def model_fn_flux_image( guidance=None, text_ids=None, image_ids=None, + kontext_latents=None, + kontext_image_ids=None, controlnet_inputs=None, controlnet_conditionings=None, tiled=False, @@ -787,6 +819,11 @@ def model_fn_flux_image( height, width = hidden_states.shape[-2:] hidden_states = dit.patchify(hidden_states) + # Kontext + if kontext_latents is not None: + image_ids = torch.concat([image_ids, kontext_image_ids], dim=-2) + hidden_states = torch.concat([hidden_states, kontext_latents], dim=1) + # Step1x if step1x_reference_latents is not None: step1x_reference_image_ids = dit.prepare_image_ids(step1x_reference_latents) @@ -827,7 +864,10 @@ def model_fn_flux_image( ) # ControlNet if controlnet is not None and controlnet_conditionings is not None and controlnet_res_stack is not None: - hidden_states = hidden_states + controlnet_res_stack[block_id] + if kontext_latents is None: + hidden_states = hidden_states + controlnet_res_stack[block_id] + else: + hidden_states[:, :-kontext_latents.shape[1]] = hidden_states[:, :-kontext_latents.shape[1]] + controlnet_res_stack[block_id] # Single Blocks hidden_states = torch.cat([prompt_emb, hidden_states], dim=1) @@ -846,7 +886,10 @@ def model_fn_flux_image( ) # ControlNet if controlnet is not None and controlnet_conditionings is not None and controlnet_single_res_stack is not None: - hidden_states[:, prompt_emb.shape[1]:] = hidden_states[:, prompt_emb.shape[1]:] + controlnet_single_res_stack[block_id] + if kontext_latents is None: + hidden_states[:, prompt_emb.shape[1]:] = hidden_states[:, prompt_emb.shape[1]:] + controlnet_single_res_stack[block_id] + else: + hidden_states[:, prompt_emb.shape[1]:-kontext_latents.shape[1]] = hidden_states[:, prompt_emb.shape[1]:-kontext_latents.shape[1]] + controlnet_single_res_stack[block_id] hidden_states = hidden_states[:, prompt_emb.shape[1]:] if tea_cache is not None: @@ -858,6 +901,10 @@ def model_fn_flux_image( # Step1x if step1x_reference_latents is not None: hidden_states = hidden_states[:, :hidden_states.shape[1] // 2] + + # Kontext + if kontext_latents is not None: + hidden_states = hidden_states[:, :-kontext_latents.shape[1]] hidden_states = dit.unpatchify(hidden_states, height, width) diff --git a/download.py b/download.py deleted file mode 100644 index 1404010..0000000 --- a/download.py +++ /dev/null @@ -1,3 +0,0 @@ -#模型下载 -from modelscope import snapshot_download -model_dir = snapshot_download('black-forest-labs/FLUX.1-Kontext-dev', cache_dir="models", ignore_file_pattern="transformer/*") \ No newline at end of file diff --git a/examples/flux/model_inference/FLUX.1-Kontext-dev.py b/examples/flux/model_inference/FLUX.1-Kontext-dev.py new file mode 100644 index 0000000..3d0e921 --- /dev/null +++ b/examples/flux/model_inference/FLUX.1-Kontext-dev.py @@ -0,0 +1,54 @@ +import torch +from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig +from PIL import Image + + +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-Kontext-dev", origin_file_pattern="flux1-kontext-dev.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), + ], +) + +image_1 = pipe( + prompt="a beautiful Asian long-haired female college student.", + embedded_guidance=2.5, + seed=1, +) +image_1.save("image_1.jpg") + +image_2 = pipe( + prompt="transform the style to anime style.", + kontext_images=image_1, + embedded_guidance=2.5, + seed=2, +) +image_2.save("image_2.jpg") + +image_3 = pipe( + prompt="let her smile.", + kontext_images=image_1, + embedded_guidance=2.5, + seed=3, +) +image_3.save("image_3.jpg") + +image_4 = pipe( + prompt="let the girl play basketball.", + kontext_images=image_1, + embedded_guidance=2.5, + seed=4, +) +image_4.save("image_4.jpg") + +image_5 = pipe( + prompt="move the girl to a park, let her sit on a chair.", + kontext_images=image_1, + embedded_guidance=2.5, + seed=5, +) +image_5.save("image_5.jpg") \ No newline at end of file diff --git a/examples/flux/model_training/lora/FLUX.1-Kontext-dev.sh b/examples/flux/model_training/lora/FLUX.1-Kontext-dev.sh new file mode 100644 index 0000000..814d7ad --- /dev/null +++ b/examples/flux/model_training/lora/FLUX.1-Kontext-dev.sh @@ -0,0 +1,17 @@ +accelerate launch examples/flux/model_training/train.py \ + --dataset_base_path data/example_image_dataset \ + --dataset_metadata_path data/example_image_dataset/metadata_kontext.csv \ + --data_file_keys "image,kontext_images" \ + --max_pixels 1048576 \ + --dataset_repeat 400 \ + --model_id_with_origin_paths "black-forest-labs/FLUX.1-Kontext-dev:flux1-kontext-dev.safetensors,black-forest-labs/FLUX.1-dev:text_encoder/model.safetensors,black-forest-labs/FLUX.1-dev:text_encoder_2/,black-forest-labs/FLUX.1-dev:ae.safetensors" \ + --learning_rate 1e-4 \ + --num_epochs 5 \ + --remove_prefix_in_ckpt "pipe.dit." \ + --output_path "./models/train/FLUX.1-Kontext-dev_lora" \ + --lora_base_model "dit" \ + --lora_target_modules "a_to_qkv,b_to_qkv,ff_a.0,ff_a.2,ff_b.0,ff_b.2,a_to_out,b_to_out,proj_out,norm.linear,norm1_a.linear,norm1_b.linear,to_qkv_mlp" \ + --lora_rank 32 \ + --align_to_opensource_format \ + --extra_inputs "kontext_images" \ + --use_gradient_checkpointing diff --git a/examples/flux/model_training/validate_lora/FLUX.1-Kontext-dev.py b/examples/flux/model_training/validate_lora/FLUX.1-Kontext-dev.py new file mode 100644 index 0000000..b61cd4b --- /dev/null +++ b/examples/flux/model_training/validate_lora/FLUX.1-Kontext-dev.py @@ -0,0 +1,24 @@ +import torch +from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig +from PIL import Image + + +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-Kontext-dev", origin_file_pattern="flux1-kontext-dev.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), + ], +) +pipe.load_lora(pipe.dit, "models/train/FLUX.1-Kontext-dev_lora/epoch-4.safetensors", alpha=1) + +image = pipe( + prompt="Make the dog turn its head around.", + kontext_images=Image.open("data/example_image_dataset/2.jpg").resize((768, 768)), + height=768, width=768, + seed=0 +) +image.save("image_FLUX.1-Kontext-dev_lora.jpg") From 8c226e83a614461d0c62493960acfba3da4bc86a Mon Sep 17 00:00:00 2001 From: Artiprocher Date: Sun, 29 Jun 2025 15:51:45 +0800 Subject: [PATCH 13/14] flux-kontext --- diffsynth/pipelines/flux_image_new.py | 118 ++++++- examples/flux/README.md | 0 examples/flux/README_zh.md | 326 ++++++++++++++++++ .../teacache.py} | 0 4 files changed, 442 insertions(+), 2 deletions(-) create mode 100644 examples/flux/README.md create mode 100644 examples/flux/README_zh.md rename examples/flux/{model_inference/FLUX.1-dev-TeaCache.py => acceleration/teacache.py} (100%) diff --git a/diffsynth/pipelines/flux_image_new.py b/diffsynth/pipelines/flux_image_new.py index 1568efb..10c737a 100644 --- a/diffsynth/pipelines/flux_image_new.py +++ b/diffsynth/pipelines/flux_image_new.py @@ -23,7 +23,9 @@ from ..models.tiler import FastTileWorker from .wan_video_new import BasePipeline, ModelConfig, PipelineUnitRunner, PipelineUnit from ..lora.flux_lora import FluxLoRALoader -from ..vram_management import gradient_checkpoint_forward +from transformers.models.t5.modeling_t5 import T5LayerNorm, T5DenseActDense, T5DenseGatedActDense +from ..models.flux_dit import RMSNorm +from ..vram_management import gradient_checkpoint_forward, enable_vram_management, AutoWrappedModule, AutoWrappedLinear @@ -135,7 +137,119 @@ class FluxImagePipeline(BasePipeline): def enable_vram_management(self, num_persistent_param_in_dit=None, vram_limit=None, vram_buffer=0.5): - pass + self.vram_management_enabled = True + if num_persistent_param_in_dit is not None: + vram_limit = None + else: + if vram_limit is None: + vram_limit = self.get_vram() + vram_limit = vram_limit - vram_buffer + if self.text_encoder_1 is not None: + dtype = next(iter(self.text_encoder_1.parameters())).dtype + enable_vram_management( + self.text_encoder_1, + module_map = { + torch.nn.Linear: AutoWrappedLinear, + torch.nn.Embedding: AutoWrappedModule, + torch.nn.LayerNorm: AutoWrappedModule, + }, + module_config = dict( + offload_dtype=dtype, + offload_device="cpu", + onload_dtype=dtype, + onload_device="cpu", + computation_dtype=self.torch_dtype, + computation_device=self.device, + ), + vram_limit=vram_limit, + ) + if self.text_encoder_2 is not None: + dtype = next(iter(self.text_encoder_2.parameters())).dtype + enable_vram_management( + self.text_encoder_2, + module_map = { + torch.nn.Linear: AutoWrappedLinear, + torch.nn.Embedding: AutoWrappedModule, + T5LayerNorm: AutoWrappedModule, + T5DenseActDense: AutoWrappedModule, + T5DenseGatedActDense: AutoWrappedModule, + }, + module_config = dict( + offload_dtype=dtype, + offload_device="cpu", + onload_dtype=dtype, + onload_device="cpu", + computation_dtype=self.torch_dtype, + computation_device=self.device, + ), + vram_limit=vram_limit, + ) + if self.dit is not None: + dtype = next(iter(self.dit.parameters())).dtype + device = "cpu" if vram_limit is not None else self.device + enable_vram_management( + self.dit, + module_map = { + RMSNorm: AutoWrappedModule, + torch.nn.Linear: AutoWrappedLinear, + }, + module_config = dict( + offload_dtype=dtype, + offload_device="cpu", + onload_dtype=dtype, + onload_device=device, + computation_dtype=self.torch_dtype, + computation_device=self.device, + ), + max_num_param=num_persistent_param_in_dit, + overflow_module_config = dict( + offload_dtype=dtype, + offload_device="cpu", + onload_dtype=dtype, + onload_device="cpu", + computation_dtype=self.torch_dtype, + computation_device=self.device, + ), + vram_limit=vram_limit, + ) + if self.vae_decoder is not None: + dtype = next(iter(self.vae_decoder.parameters())).dtype + enable_vram_management( + self.vae_decoder, + module_map = { + torch.nn.Linear: AutoWrappedLinear, + torch.nn.Conv2d: AutoWrappedModule, + torch.nn.GroupNorm: AutoWrappedModule, + }, + module_config = dict( + offload_dtype=dtype, + offload_device="cpu", + onload_dtype=dtype, + onload_device="cpu", + computation_dtype=self.torch_dtype, + computation_device=self.device, + ), + vram_limit=vram_limit, + ) + if self.vae_encoder is not None: + dtype = next(iter(self.vae_encoder.parameters())).dtype + enable_vram_management( + self.vae_encoder, + module_map = { + torch.nn.Linear: AutoWrappedLinear, + torch.nn.Conv2d: AutoWrappedModule, + torch.nn.GroupNorm: AutoWrappedModule, + }, + module_config = dict( + offload_dtype=dtype, + offload_device="cpu", + onload_dtype=dtype, + onload_device="cpu", + computation_dtype=self.torch_dtype, + computation_device=self.device, + ), + vram_limit=vram_limit, + ) @staticmethod diff --git a/examples/flux/README.md b/examples/flux/README.md new file mode 100644 index 0000000..e69de29 diff --git a/examples/flux/README_zh.md b/examples/flux/README_zh.md new file mode 100644 index 0000000..bb87279 --- /dev/null +++ b/examples/flux/README_zh.md @@ -0,0 +1,326 @@ +# FLUX + +[Switch to English](./README.md) + +FLUX 是由 Black-Forest-Labs 开源的一系列图像生成模型。 + +**DiffSynth-Studio 启用了新的推理和训练框架,如需使用旧版本,请点击[这里](https://github.com/modelscope/DiffSynth-Studio/tree/3edf3583b1f08944cee837b94d9f84d669c2729c)。** + +## 安装 + +在使用本系列模型之前,请通过源码安装 DiffSynth-Studio。 + +```shell +git clone https://github.com/modelscope/DiffSynth-Studio.git +cd DiffSynth-Studio +pip install -e . +``` + +## 快速开始 + +通过运行以下代码可以快速加载 FLUX.1-dev 模型并进行推理。 + +```python +import torch +from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig + +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), + ], +) + +image = pipe(prompt="a cat", seed=0) +image.save("image.jpg") +``` + +## 模型总览 + +**FLUX 系列模型的全新框架支持正在开发中,敬请期待!** + +|模型 ID|额外参数|推理|全量训练|全量训练后验证|LoRA 训练|LoRA 训练后验证| +|-|-|-|-|-|-|-| +|[black-forest-labs/FLUX.1-dev](https://modelscope.cn/models/black-forest-labs/FLUX.1-dev)||[code](./model_inference/FLUX.1-dev.py)|[code](./model_training/full/FLUX.1-dev.sh)|[code](./model_training/validate_full/FLUX.1-dev.py)|[code](./model_training/lora/FLUX.1-dev.sh)|[code](./model_training/validate_lora/FLUX.1-dev.py)| +|[black-forest-labs/FLUX.1-Kontext-dev](https://modelscope.cn/models/black-forest-labs/FLUX.1-Kontext-dev)|`kontext_images`|[code](./model_inference/FLUX.1-Kontext-dev.py)|||[code](./model_training/lora/FLUX.1-Kontext-dev.sh)|[code](./model_training/validate_lora/FLUX.1-Kontext-dev.py)| + +## 模型推理 + +以下部分将会帮助您理解我们的功能并编写推理代码。 + +
+ +加载模型 + +模型通过 `from_pretrained` 加载: + +```python +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), + ], +) +``` + +其中 `torch_dtype` 和 `device` 是计算精度和计算设备。`model_configs` 可通过多种方式配置模型路径: + +* 从[魔搭社区](https://modelscope.cn/)下载模型并加载。此时需要填写 `model_id` 和 `origin_file_pattern`,例如 + +```python +ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors") +``` + +* 从本地文件路径加载模型。此时需要填写 `path`,例如 + +```python +ModelConfig(path="models/black-forest-labs/FLUX.1-dev/flux1-dev.safetensors") +``` + +对于从多个文件加载的单一模型,使用列表即可,例如 + +```python +ModelConfig(path=[ + "models/xxx/diffusion_pytorch_model-00001-of-00003.safetensors", + "models/xxx/diffusion_pytorch_model-00002-of-00003.safetensors", + "models/xxx/diffusion_pytorch_model-00003-of-00003.safetensors", +]) +``` + +`from_pretrained` 还提供了额外的参数用于控制模型加载时的行为: + +* `local_model_path`: 用于保存下载模型的路径,默认值为 `"./models"`。 +* `skip_download`: 是否跳过下载,默认值为 `False`。当您的网络无法访问[魔搭社区](https://modelscope.cn/)时,请手动下载必要的文件,并将其设置为 `True`。 + +
+ + +
+ +显存管理 + +DiffSynth-Studio 为 FLUX 模型提供了细粒度的显存管理,让模型能够在低显存设备上进行推理,可通过以下代码开启 offload 功能,在显存有限的设备上将部分模块 offload 到内存中。 + +```python +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors", offload_device="cpu"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors", offload_device="cpu"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/", offload_device="cpu"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors", offload_device="cpu"), + ], +) +pipe.enable_vram_management() +``` + +`enable_vram_management` 函数提供了以下参数,用于控制显存使用情况: + +* `vram_limit`: 显存占用量(GB),默认占用设备上的剩余显存。注意这不是一个绝对限制,当设置的显存不足以支持模型进行推理,但实际可用显存足够时,将会以最小化显存占用的形式进行推理。将其设置为0时,将会实现理论最小显存占用。 +* `vram_buffer`: 显存缓冲区大小(GB),默认为 0.5GB。由于部分较大的神经网络层在 onload 阶段会不可控地占用更多显存,因此一个显存缓冲区是必要的,理论上的最优值为模型中最大的层所占的显存。 +* `num_persistent_param_in_dit`: DiT 模型中常驻显存的参数数量(个),默认为无限制。我们将会在未来删除这个参数,请不要依赖这个参数。 + +
+ + +
+ +推理加速 + +* TeaCache:加速技术 [TeaCache](https://github.com/ali-vilab/TeaCache),请参考[示例代码](./acceleration/teacache.py)。 + +
+ +
+ +输入参数 + +Pipeline 在推理阶段能够接收以下输入参数: + +* `prompt`: 提示词,描述画面中出现的内容。 +* `negative_prompt`: 负向提示词,描述画面中不应该出现的内容,默认值为 `""`。 +* `cfg_scale`: Classifier-free guidance 的参数,默认值为 1,当设置为大于1的数值时生效。 +* `embedded_guidance`: FLUX-dev 的内嵌引导参数,默认值为 3.5。 +* `t5_sequence_length`: T5 模型的文本向量序列长度,默认值为 512。 +* `input_image`: 输入图像,用于图生图,该参数与 `denoising_strength` 配合使用。 +* `denoising_strength`: 去噪强度,范围是 0~1,默认值为 1,当数值接近 0 时,生成图像与输入图像相似;当数值接近 1 时,生成图像与输入图像相差更大。在不输入 `input_image` 参数时,请不要将其设置为非 1 的数值。 +* `height`: 图像高度,需保证高度为 16 的倍数。 +* `width`: 图像宽度,需保证宽度为 16 的倍数。 +* `seed`: 随机种子。默认为 `None`,即完全随机。 +* `rand_device`: 生成随机高斯噪声矩阵的计算设备,默认为 `"cpu"`。当设置为 `cuda` 时,在不同 GPU 上会导致不同的生成结果。 +* `sigma_shift`: Rectified Flow 理论中的参数,默认为 3。数值越大,模型在去噪的开始阶段停留的步骤数越多,可适当调大这个参数来提高画面质量,但会因生成过程与训练过程不一致导致生成的视频内容与训练数据存在差异。 +* `num_inference_steps`: 推理次数,默认值为 30。 +* `kontext_images`: Kontext 模型的输入图像。 +* `controlnet_inputs`: ControlNet 模型的输入。 +* `ipadapter_images`: IP-Adapter 模型的输入图像。 +* `ipadapter_scale`: IP-Adapter 模型的控制强度。 + +
+ + +## 模型训练 + +FLUX 系列模型训练通过统一的 [`./model_training/train.py`](./model_training/train.py) 脚本进行。 + +
+ +脚本参数 + +脚本包含以下参数: + +* 数据集 + * `--dataset_base_path`: 数据集的根路径。 + * `--dataset_metadata_path`: 数据集的元数据文件路径。 + * `--height`: 图像或视频的高度。将 `height` 和 `width` 留空以启用动态分辨率。 + * `--width`: 图像或视频的宽度。将 `height` 和 `width` 留空以启用动态分辨率。 + * `--data_file_keys`: 元数据中的数据文件键。用逗号分隔。 + * `--dataset_repeat`: 每个 epoch 中数据集重复的次数。 +* 模型 + * `--model_paths`: 要加载的模型路径。JSON 格式。 + * `--model_id_with_origin_paths`: 带原始路径的模型 ID,例如 Wan-AI/Wan2.1-T2V-1.3B:diffusion_pytorch_model*.safetensors。用逗号分隔。 +* 训练 + * `--learning_rate`: 学习率。 + * `--num_epochs`: 轮数(Epoch)数量。 + * `--output_path`: 保存路径。 + * `--remove_prefix_in_ckpt`: 在 ckpt 中移除前缀。 +* 可训练模块 + * `--trainable_models`: 可训练的模型,例如 dit、vae、text_encoder。 + * `--lora_base_model`: LoRA 添加到哪个模型上。 + * `--lora_target_modules`: LoRA 添加到哪一层上。 + * `--lora_rank`: LoRA 的秩(Rank)。 +* 额外模型输入 + * `--extra_inputs`: 额外的模型输入,以逗号分隔。 +* 显存管理 + * `use_gradient_checkpointing`: 是否启用 gradient checkpointing。 + * `--use_gradient_checkpointing_offload`: 是否将 gradient checkpointing 卸载到内存中。 + * `gradient_accumulation_steps`: 梯度累积步数。 +* 其他 + * `--align_to_opensource_format`: 是否将 FLUX DiT LoRA 的格式与开源版本对齐,仅对 FLUX.1-dev 和 FLUX.1-Kontext-dev 的 LoRA 训练生效。 + + +此外,训练框架基于 [`accelerate`](https://huggingface.co/docs/accelerate/index) 构建,在开始训练前运行 `accelerate config` 可配置 GPU 的相关参数。对于部分模型训练(例如模型的全量训练)脚本,我们提供了建议的 `accelerate` 配置文件,可在对应的训练脚本中查看。 + +
+ + +
+ +Step 1: 准备数据集 + +数据集包含一系列文件,我们建议您这样组织数据集文件: + +``` +data/example_video_dataset/ +├── metadata.csv +├── image1.jpg +└── image2.jpg +``` + +其中 `image1.jpg`、`image2.jpg` 为训练用视频数据,`metadata.csv` 为元数据列表,例如 + +``` +video,prompt +image1.jpg,"a cat is sleeping" +image2.jpg,"a dog is running" +``` + +我们构建了一个样例视频数据集,以方便您进行测试,通过以下命令可以下载这个数据集: + +```shell +modelscope download --dataset DiffSynth-Studio/example_image_dataset --local_dir ./data/example_image_dataset +``` + +数据集支持多种图片格式,`"jpg", "jpeg", "png", "webp"`。 + +图片的尺寸可通过脚本参数 `--height`、`--width` 控制。当 `--height` 和 `--width` 为空时将会开启动态分辨率,按照数据集中每个视频或图片的实际宽高训练。 + +**我们强烈建议使用固定分辨率训练,因为在多卡训练中存在负载均衡问题。** + +当模型需要额外输入时,例如具备控制能力的模型 [`black-forest-labs/FLUX.1-Kontext-dev`](https://modelscope.cn/models/black-forest-labs/FLUX.1-Kontext-dev) 所需的 `kontext_images`,请在数据集中补充相应的列,例如: + +``` +video,prompt,kontext_images +image1.jpg,"a cat is sleeping",image1_reference.jpg +``` + +额外输入若包含视频和图像文件,则需要在 `--data_file_keys` 参数中指定要解析的列名。可根据额外输入增加相应的列名,例如 `--data_file_keys "image,kontext_images"`。 + +
+ + +
+ +Step 2: 加载模型 + +类似于推理时的模型加载逻辑,可直接通过模型 ID 配置要加载的模型。例如,推理时我们通过以下设置加载模型 + +```python +model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), +] +``` + +那么在训练时,填入以下参数即可加载对应的模型。 + +```shell +--model_id_with_origin_paths "black-forest-labs/FLUX.1-dev:flux1-dev.safetensors,black-forest-labs/FLUX.1-dev:text_encoder/model.safetensors,black-forest-labs/FLUX.1-dev:text_encoder_2/,black-forest-labs/FLUX.1-dev:ae.safetensors" +``` + +如果您希望从本地文件加载模型,例如推理时 + +```python +model_configs=[ + ModelConfig(path="models/black-forest-labs/FLUX.1-dev/flux1-dev.safetensors"), + ModelConfig(path="models/black-forest-labs/FLUX.1-dev/text_encoder/model.safetensors"), + ModelConfig(path="models/black-forest-labs/FLUX.1-dev/text_encoder_2/"), + ModelConfig(path="models/black-forest-labs/FLUX.1-dev/ae.safetensors"), +] +``` + +那么训练时需设置为 + +```shell +--model_paths '[ + "models/black-forest-labs/FLUX.1-dev/flux1-dev.safetensors", + "models/black-forest-labs/FLUX.1-dev/text_encoder/model.safetensors", + "models/black-forest-labs/FLUX.1-dev/text_encoder_2/", + "models/black-forest-labs/FLUX.1-dev/ae.safetensors" +]' \ +``` + +
+ + +
+ +Step 3: 设置可训练模块 + +训练框架支持训练基础模型,或 LoRA 模型。以下是几个例子: + +* 全量训练 DiT 部分:`--trainable_models dit` +* 训练 DiT 部分的 LoRA 模型:`--lora_base_model dit --lora_target_modules "a_to_qkv,b_to_qkv,ff_a.0,ff_a.2,ff_b.0,ff_b.2,a_to_out,b_to_out,proj_out,norm.linear,norm1_a.linear,norm1_b.linear,to_qkv_mlp" --lora_rank 32` + +此外,由于训练脚本中加载了多个模块(text encoder、dit、vae),保存模型文件时需要移除前缀,例如在全量训练 DiT 部分或者训练 DiT 部分的 LoRA 模型时,请设置 `--remove_prefix_in_ckpt pipe.dit.` + +
+ + +
+ +Step 4: 启动训练程序 + +我们为每一个模型编写了训练命令,请参考本文档开头的表格。 + +
diff --git a/examples/flux/model_inference/FLUX.1-dev-TeaCache.py b/examples/flux/acceleration/teacache.py similarity index 100% rename from examples/flux/model_inference/FLUX.1-dev-TeaCache.py rename to examples/flux/acceleration/teacache.py From 44e2eecdf180545c0d955f384d232d4ab8f6c29a Mon Sep 17 00:00:00 2001 From: Artiprocher Date: Sun, 29 Jun 2025 15:59:04 +0800 Subject: [PATCH 14/14] flux-kontext --- examples/flux/README.md | 317 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) diff --git a/examples/flux/README.md b/examples/flux/README.md index e69de29..a04ecd3 100644 --- a/examples/flux/README.md +++ b/examples/flux/README.md @@ -0,0 +1,317 @@ +# FLUX + +[Switch to Chinese](./README_zh.md) + +FLUX is a series of image generation models open-sourced by Black-Forest-Labs. + +**DiffSynth-Studio has introduced a new inference and training framework. If you need to use the old version, please click [here](https://github.com/modelscope/DiffSynth-Studio/tree/3edf3583b1f08944cee837b94d9f84d669c2729c).** + +## Installation + +Before using these models, please install DiffSynth-Studio from source code: + +```shell +git clone https://github.com/modelscope/DiffSynth-Studio.git +cd DiffSynth-Studio +pip install -e . +``` + +## Quick Start + +You can quickly load the FLUX.1-dev model and perform inference by running the following code: + +```python +import torch +from diffsynth.pipelines.flux_image_new import FluxImagePipeline, ModelConfig + +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), + ], +) + +image = pipe(prompt="a cat", seed=0) +image.save("image.jpg") +``` + +## Model Overview + +**Support for the new framework of the FLUX series models is under active development. Stay tuned!** + +| Model ID | Additional Parameters | Inference | Full Training | Validation After Full Training | LoRA Training | Validation After LoRA Training | +|---------|------------------------|-----------|---------------|-------------------------------|---------------|--------------------------------| +| [black-forest-labs/FLUX.1-dev](https://modelscope.cn/models/black-forest-labs/FLUX.1-dev) | | [code](./model_inference/FLUX.1-dev.py) | [code](./model_training/full/FLUX.1-dev.sh) | [code](./model_training/validate_full/FLUX.1-dev.py) | [code](./model_training/lora/FLUX.1-dev.sh) | [code](./model_training/validate_lora/FLUX.1-dev.py) | +| [black-forest-labs/FLUX.1-Kontext-dev](https://modelscope.cn/models/black-forest-labs/FLUX.1-Kontext-dev) | `kontext_images` | [code](./model_inference/FLUX.1-Kontext-dev.py) | | | [code](./model_training/lora/FLUX.1-Kontext-dev.sh) | [code](./model_training/validate_lora/FLUX.1-Kontext-dev.py) | + +## Model Inference + +The following sections will help you understand our features and write inference code. + +
+ +Loading Models + +Models are loaded using `from_pretrained`: + +```python +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), + ], +) +``` + +Here, `torch_dtype` and `device` refer to the computation precision and device, respectively. The `model_configs` can be configured in various ways to specify model paths: + +* Download the model from [ModelScope Community](https://modelscope.cn/) and load it. In this case, provide `model_id` and `origin_file_pattern`, for example: + +```python +ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors") +``` + +* Load the model from a local file path. In this case, provide the `path`, for example: + +```python +ModelConfig(path="models/black-forest-labs/FLUX.1-dev/flux1-dev.safetensors") +``` + +For models that consist of multiple files, use a list as follows: + +```python +ModelConfig(path=[ + "models/xxx/diffusion_pytorch_model-00001-of-00003.safetensors", + "models/xxx/diffusion_pytorch_model-00002-of-00003.safetensors", + "models/xxx/diffusion_pytorch_model-00003-of-00003.safetensors", +]) +``` + +The `from_pretrained` method also provides additional parameters to control model loading behavior: + +* `local_model_path`: Path for saving downloaded models. The default is `"./models"`. +* `skip_download`: Whether to skip downloading models. The default is `False`. If your network cannot access [ModelScope Community](https://modelscope.cn/), manually download the required files and set this to `True`. + +
+ + +
+ +VRAM Management + +DiffSynth-Studio provides fine-grained VRAM management for FLUX models, enabling inference on devices with limited VRAM. You can enable offloading functionality via the following code, which moves certain modules to system memory on devices with limited GPU memory. + +```python +pipe = FluxImagePipeline.from_pretrained( + torch_dtype=torch.bfloat16, + device="cuda", + model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors", offload_device="cpu"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors", offload_device="cpu"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/", offload_device="cpu"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors", offload_device="cpu"), + ], +) +pipe.enable_vram_management() +``` + +The `enable_vram_management` function provides the following parameters to control VRAM usage: + +* `vram_limit`: VRAM usage limit in GB. By default, it uses the remaining VRAM available on the device. Note that this is not an absolute limit; if the set VRAM is insufficient but more VRAM is actually available, the model will run with minimal VRAM consumption. Setting it to 0 achieves the theoretical minimum VRAM usage. +* `vram_buffer`: VRAM buffer size in GB. The default is 0.5GB. Since some large neural network layers may consume extra VRAM during onload phases, a VRAM buffer is necessary. Ideally, the optimal value should match the VRAM occupied by the largest layer in the model. +* `num_persistent_param_in_dit`: Number of persistent parameters in the DiT model (default: no limit). We plan to remove this parameter in the future, so please avoid relying on it. + +
+ +
+ +Inference Acceleration + +* TeaCache: Acceleration technique [TeaCache](https://github.com/ali-vilab/TeaCache), please refer to the [sample code](./acceleration/teacache.py). + +
+ +
+ +Input Parameters + +The pipeline accepts the following input parameters during inference: + +* `prompt`: Prompt describing what should appear in the image. +* `negative_prompt`: Negative prompt describing what should **not** appear in the image. Default is `""`. +* `cfg_scale`: Classifier-free guidance scale. Default is 1. It becomes effective when set to a value greater than 1. +* `embedded_guidance`: Embedded guidance parameter for FLUX-dev. Default is 3.5. +* `t5_sequence_length`: Sequence length of T5 text embeddings. Default is 512. +* `input_image`: Input image used for image-to-image generation. This works together with `denoising_strength`. +* `denoising_strength`: Denoising strength, ranging from 0 to 1. Default is 1. When close to 0, the generated image will be similar to the input image; when close to 1, the generated image will differ significantly from the input. Do not set this to a non-1 value if no `input_image` is provided. +* `height`: Height of the generated image. Must be a multiple of 16. +* `width`: Width of the generated image. Must be a multiple of 16. +* `seed`: Random seed. Default is `None`, meaning completely random. +* `rand_device`: Device for generating random Gaussian noise. Default is `"cpu"`. Setting it to `"cuda"` may lead to different results across GPUs. +* `sigma_shift`: Parameter from Rectified Flow theory. Default is 3. A larger value increases the number of steps spent at the beginning of denoising and can improve image quality. However, it may cause inconsistencies between the generation process and training data. +* `num_inference_steps`: Number of inference steps. Default is 30. +* `kontext_images`: Input images for the Kontext model. +* `controlnet_inputs`: Inputs for the ControlNet model. +* `ipadapter_images`: Input images for the IP-Adapter model. +* `ipadapter_scale`: Control strength of the IP-Adapter model. + +
+ +## Model Training + +FLUX series models are trained using a unified script [`./model_training/train.py`](./model_training/train.py). + +
+ +Script Parameters + +The script supports the following parameters: + +* Dataset + * `--dataset_base_path`: Root path to the dataset. + * `--dataset_metadata_path`: Path to the metadata file of the dataset. + * `--height`: Height of images or videos. Leave `height` and `width` empty to enable dynamic resolution. + * `--width`: Width of images or videos. Leave `height` and `width` empty to enable dynamic resolution. + * `--data_file_keys`: Keys in metadata for data files. Comma-separated. + * `--dataset_repeat`: Number of times the dataset repeats per epoch. +* Models + * `--model_paths`: Paths to load models. JSON format. + * `--model_id_with_origin_paths`: Model IDs with original paths, e.g., Wan-AI/Wan2.1-T2V-1.3B:diffusion_pytorch_model*.safetensors. Comma-separated. +* Training + * `--learning_rate`: Learning rate. + * `--num_epochs`: Number of training epochs. + * `--output_path`: Output path for saving checkpoints. + * `--remove_prefix_in_ckpt`: Remove prefix in checkpoint filenames. +* Trainable Modules + * `--trainable_models`: Models that can be trained, e.g., dit, vae, text_encoder. + * `--lora_base_model`: Which base model to apply LoRA on. + * `--lora_target_modules`: Which layers to apply LoRA on. + * `--lora_rank`: Rank of LoRA. +* Extra Inputs + * `--extra_inputs`: Additional model inputs. Comma-separated. +* VRAM Management + * `use_gradient_checkpointing`: Whether to use gradient checkpointing. + * `--use_gradient_checkpointing_offload`: Whether to offload gradient checkpointing to CPU memory. + * `gradient_accumulation_steps`: Number of steps for gradient accumulation. +* Miscellaneous + * `--align_to_opensource_format`: Whether to align the FLUX DiT LoRA format with the open-source version. Only applicable to LoRA training for FLUX.1-dev and FLUX.1-Kontext-dev. + +
+ +
+ +Step 1: Prepare Dataset + +The dataset contains a series of files. We recommend organizing your dataset files as follows: + +``` +data/example_video_dataset/ +├── metadata.csv +├── image1.jpg +└── image2.jpg +``` + +Here, `image1.jpg`, `image2.jpg` are training video/image data, and `metadata.csv` is the metadata list, for example: + +``` +video,prompt +image1.jpg,"a cat is sleeping" +image2.jpg,"a dog is running" +``` + +We have built a sample image dataset to help you test more conveniently. You can download this dataset using the following command: + +```shell +modelscope download --dataset DiffSynth-Studio/example_image_dataset --local_dir ./data/example_image_dataset +``` + +The dataset supports multiple image formats: `"jpg", "jpeg", "png", "webp"`. + +The image resolution can be controlled via script parameters `--height` and `--width`. When both `--height` and `--width` are left empty, dynamic resolution will be enabled, allowing training with the actual width and height of each video or image in the dataset. + +**We strongly recommend using fixed-resolution training, as there may be load-balancing issues in multi-GPU training with dynamic resolution.** + +When the model requires additional inputs—for instance, `kontext_images` required by the controllable model [`black-forest-labs/FLUX.1-Kontext-dev`](https://modelscope.cn/models/black-forest-labs/FLUX.1-Kontext-dev)—please add corresponding columns in the dataset, for example: + +``` +video,prompt,kontext_images +image1.jpg,"a cat is sleeping",image1_reference.jpg +``` + +If additional inputs include video or image files, you need to specify the column names to parse using the `--data_file_keys` parameter. You can add more column names accordingly, e.g., `--data_file_keys "image,kontext_images"`. + +
+ +
+ +Step 2: Load Model + +Similar to the model loading logic during inference, you can directly configure the model to be loaded using its model ID. For example, during inference we load the model with the following configuration: + +```python +model_configs=[ + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="flux1-dev.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder/model.safetensors"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="text_encoder_2/"), + ModelConfig(model_id="black-forest-labs/FLUX.1-dev", origin_file_pattern="ae.safetensors"), +] +``` + +Then during training, simply provide the following parameter to load the corresponding model: + +```shell +--model_id_with_origin_paths "black-forest-labs/FLUX.1-dev:flux1-dev.safetensors,black-forest-labs/FLUX.1-dev:text_encoder/model.safetensors,black-forest-labs/FLUX.1-dev:text_encoder_2/,black-forest-labs/FLUX.1-dev:ae.safetensors" +``` + +If you prefer to load the model from local files, as in the inference example: + +```python +model_configs=[ + ModelConfig(path="models/black-forest-labs/FLUX.1-dev/flux1-dev.safetensors"), + ModelConfig(path="models/black-forest-labs/FLUX.1-dev/text_encoder/model.safetensors"), + ModelConfig(path="models/black-forest-labs/FLUX.1-dev/text_encoder_2/"), + ModelConfig(path="models/black-forest-labs/FLUX.1-dev/ae.safetensors"), +] +``` + +Then during training, set it up as follows: + +```shell +--model_paths '[ + "models/black-forest-labs/FLUX.1-dev/flux1-dev.safetensors", + "models/black-forest-labs/FLUX.1-dev/text_encoder/model.safetensors", + "models/black-forest-labs/FLUX.1-dev/text_encoder_2/", + "models/black-forest-labs/FLUX.1-dev/ae.safetensors" +]' \ +``` + +
+ +
+ +Step 3: Configure Trainable Modules + +The training framework supports both full-model training and LoRA-based fine-tuning. Below are some examples: + +* Full training of the DiT module: `--trainable_models dit` +* Training a LoRA model on the DiT module: `--lora_base_model dit --lora_target_modules "a_to_qkv,b_to_qkv,ff_a.0,ff_a.2,ff_b.0,ff_b.2,a_to_out,b_to_out,proj_out,norm.linear,norm1_a.linear,norm1_b.linear,to_qkv_mlp" --lora_rank 32` + +Additionally, since the training script loads multiple modules (text encoder, DiT, VAE), you need to remove prefixes when saving the model files. For example, when performing full DiT training or LoRA training on the DiT module, please set `--remove_prefix_in_ckpt pipe.dit.` + +
+ +
+ +Step 4: Launch the Training Script + +We have written specific training commands for each model. Please refer to the table at the beginning of this document for details. + +