Refactor: Remove ConfigControlnet
This commit is contained in:
parent
22f98fc5a4
commit
e4af40e4ee
@ -1,4 +1,4 @@
|
|||||||
from mflux.config.config import Config, ConfigControlnet
|
from mflux.config.config import Config
|
||||||
from mflux.config.model_config import ModelConfig, ModelLookup
|
from mflux.config.model_config import ModelConfig, ModelLookup
|
||||||
from mflux.controlnet.flux_controlnet import Flux1Controlnet
|
from mflux.controlnet.flux_controlnet import Flux1Controlnet
|
||||||
from mflux.error.exceptions import StopImageGenerationException
|
from mflux.error.exceptions import StopImageGenerationException
|
||||||
@ -9,7 +9,6 @@ __all__ = [
|
|||||||
"Flux1",
|
"Flux1",
|
||||||
"Flux1Controlnet",
|
"Flux1Controlnet",
|
||||||
"Config",
|
"Config",
|
||||||
"ConfigControlnet",
|
|
||||||
"ModelConfig",
|
"ModelConfig",
|
||||||
"ModelLookup",
|
"ModelLookup",
|
||||||
"ImageUtil",
|
"ImageUtil",
|
||||||
|
|||||||
@ -17,6 +17,7 @@ class Config:
|
|||||||
guidance: float = 4.0,
|
guidance: float = 4.0,
|
||||||
init_image_path: Path | None = None,
|
init_image_path: Path | None = None,
|
||||||
init_image_strength: float | None = None,
|
init_image_strength: float | None = None,
|
||||||
|
controlnet_strength: float | None = None,
|
||||||
):
|
):
|
||||||
if width % 16 != 0 or height % 16 != 0:
|
if width % 16 != 0 or height % 16 != 0:
|
||||||
log.warning("Width and height should be multiples of 16. Rounding down.")
|
log.warning("Width and height should be multiples of 16. Rounding down.")
|
||||||
@ -26,16 +27,4 @@ class Config:
|
|||||||
self.guidance = guidance
|
self.guidance = guidance
|
||||||
self.init_image_path = init_image_path
|
self.init_image_path = init_image_path
|
||||||
self.init_image_strength = init_image_strength
|
self.init_image_strength = init_image_strength
|
||||||
|
|
||||||
|
|
||||||
class ConfigControlnet(Config):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
num_inference_steps: int = 4,
|
|
||||||
width: int = 1024,
|
|
||||||
height: int = 1024,
|
|
||||||
guidance: float = 4.0,
|
|
||||||
controlnet_strength: float = 1.0,
|
|
||||||
):
|
|
||||||
super().__init__(num_inference_steps=num_inference_steps, width=width, height=height, guidance=guidance)
|
|
||||||
self.controlnet_strength = controlnet_strength
|
self.controlnet_strength = controlnet_strength
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import logging
|
|||||||
import mlx.core as mx
|
import mlx.core as mx
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from mflux.config.config import Config, ConfigControlnet
|
from mflux.config.config import Config
|
||||||
from mflux.config.model_config import ModelConfig
|
from mflux.config.model_config import ModelConfig
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -12,7 +12,7 @@ logger = logging.getLogger(__name__)
|
|||||||
class RuntimeConfig:
|
class RuntimeConfig:
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
config: Config | ConfigControlnet,
|
config: Config,
|
||||||
model_config: ModelConfig,
|
model_config: ModelConfig,
|
||||||
):
|
):
|
||||||
self.config = config
|
self.config = config
|
||||||
@ -54,23 +54,20 @@ class RuntimeConfig:
|
|||||||
@property
|
@property
|
||||||
def init_time_step(self) -> int:
|
def init_time_step(self) -> int:
|
||||||
if self.config.init_image_path is None:
|
if self.config.init_image_path is None:
|
||||||
# text to image, always begin at time step 0
|
# For text-to-image, always begin at time step 0.
|
||||||
return 0
|
return 0
|
||||||
else:
|
else:
|
||||||
# we skip to the time step as informed by the init_image_strength
|
# For image-to-image: higher strength means we skip more steps.
|
||||||
# the higher the strength number, the more time steps we skip
|
|
||||||
strength = max(0.0, min(1.0, self.config.init_image_strength))
|
strength = max(0.0, min(1.0, self.config.init_image_strength))
|
||||||
# if the strength is too small to even influence the image
|
|
||||||
# help the user round up so the init_image has influence at step 1
|
|
||||||
t = max(1, int(self.num_inference_steps * strength))
|
t = max(1, int(self.num_inference_steps * strength))
|
||||||
return t
|
return t
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def controlnet_strength(self) -> float:
|
def controlnet_strength(self) -> float | None:
|
||||||
if isinstance(self.config, ConfigControlnet):
|
if self.config.controlnet_strength is not None:
|
||||||
return self.config.controlnet_strength
|
return self.config.controlnet_strength
|
||||||
else:
|
|
||||||
raise NotImplementedError("Controlnet conditioning scale is only available for ConfigControlnet")
|
return None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _create_sigmas(config, model) -> mx.array:
|
def _create_sigmas(config, model) -> mx.array:
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import mlx.core as mx
|
|||||||
from mlx import nn
|
from mlx import nn
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
from mflux.config.config import ConfigControlnet
|
from mflux.config.config import Config
|
||||||
from mflux.config.model_config import ModelConfig
|
from mflux.config.model_config import ModelConfig
|
||||||
from mflux.config.runtime_config import RuntimeConfig
|
from mflux.config.runtime_config import RuntimeConfig
|
||||||
from mflux.controlnet.controlnet_util import ControlnetUtil
|
from mflux.controlnet.controlnet_util import ControlnetUtil
|
||||||
@ -56,10 +56,10 @@ class Flux1Controlnet(nn.Module):
|
|||||||
output: str,
|
output: str,
|
||||||
controlnet_image_path: str,
|
controlnet_image_path: str,
|
||||||
controlnet_save_canny: bool = False,
|
controlnet_save_canny: bool = False,
|
||||||
config: ConfigControlnet = ConfigControlnet(),
|
config: Config = Config(),
|
||||||
stepwise_output_dir: Path = None,
|
stepwise_output_dir: Path = None,
|
||||||
) -> GeneratedImage:
|
) -> GeneratedImage:
|
||||||
# Create a new runtime config based on the model type and input parameters
|
# Convert the user config to a runtime config with derived parameters.
|
||||||
config = RuntimeConfig(config, self.model_config)
|
config = RuntimeConfig(config, self.model_config)
|
||||||
time_steps = tqdm(range(config.num_inference_steps))
|
time_steps = tqdm(range(config.num_inference_steps))
|
||||||
stepwise_handler = StepwiseHandler(
|
stepwise_handler = StepwiseHandler(
|
||||||
@ -135,14 +135,14 @@ class Flux1Controlnet(nn.Module):
|
|||||||
decoded = self.vae.decode(latents)
|
decoded = self.vae.decode(latents)
|
||||||
return ImageUtil.to_image(
|
return ImageUtil.to_image(
|
||||||
decoded_latents=decoded,
|
decoded_latents=decoded,
|
||||||
|
config=config,
|
||||||
seed=seed,
|
seed=seed,
|
||||||
prompt=prompt,
|
prompt=prompt,
|
||||||
quantization=self.bits,
|
quantization=self.bits,
|
||||||
generation_time=time_steps.format_dict["elapsed"],
|
|
||||||
lora_paths=self.lora_paths,
|
lora_paths=self.lora_paths,
|
||||||
lora_scales=self.lora_scales,
|
lora_scales=self.lora_scales,
|
||||||
config=config,
|
|
||||||
controlnet_image_path=controlnet_image_path,
|
controlnet_image_path=controlnet_image_path,
|
||||||
|
generation_time=time_steps.format_dict["elapsed"],
|
||||||
)
|
)
|
||||||
|
|
||||||
def save_model(self, base_path: str) -> None:
|
def save_model(self, base_path: str) -> None:
|
||||||
|
|||||||
@ -53,7 +53,7 @@ class Flux1(nn.Module):
|
|||||||
config: Config = Config(),
|
config: Config = Config(),
|
||||||
stepwise_output_dir: Path = None,
|
stepwise_output_dir: Path = None,
|
||||||
) -> GeneratedImage:
|
) -> GeneratedImage:
|
||||||
# Create a new runtime config based on the model type and input parameters
|
# Convert the user config to a runtime config with derived parameters.
|
||||||
config = RuntimeConfig(config, self.model_config)
|
config = RuntimeConfig(config, self.model_config)
|
||||||
time_steps = tqdm(range(config.init_time_step, config.num_inference_steps))
|
time_steps = tqdm(range(config.init_time_step, config.num_inference_steps))
|
||||||
stepwise_handler = StepwiseHandler(
|
stepwise_handler = StepwiseHandler(
|
||||||
@ -108,15 +108,15 @@ class Flux1(nn.Module):
|
|||||||
decoded = self.vae.decode(latents)
|
decoded = self.vae.decode(latents)
|
||||||
return ImageUtil.to_image(
|
return ImageUtil.to_image(
|
||||||
decoded_latents=decoded,
|
decoded_latents=decoded,
|
||||||
|
config=config,
|
||||||
seed=seed,
|
seed=seed,
|
||||||
prompt=prompt,
|
prompt=prompt,
|
||||||
quantization=self.bits,
|
quantization=self.bits,
|
||||||
generation_time=time_steps.format_dict["elapsed"],
|
|
||||||
lora_paths=self.lora_paths,
|
lora_paths=self.lora_paths,
|
||||||
lora_scales=self.lora_scales,
|
lora_scales=self.lora_scales,
|
||||||
init_image_path=config.init_image_path,
|
init_image_path=config.init_image_path,
|
||||||
init_image_strength=config.init_image_strength,
|
init_image_strength=config.init_image_strength,
|
||||||
config=config,
|
generation_time=time_steps.format_dict["elapsed"],
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
@ -14,7 +14,7 @@ def main():
|
|||||||
parser.add_output_arguments()
|
parser.add_output_arguments()
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# Load the model
|
# 1. Load the model
|
||||||
flux = Flux1(
|
flux = Flux1(
|
||||||
model_config=ModelLookup.from_name(model_name=args.model, base_model=args.base_model),
|
model_config=ModelLookup.from_name(model_name=args.model, base_model=args.base_model),
|
||||||
quantize=args.quantize,
|
quantize=args.quantize,
|
||||||
@ -25,7 +25,7 @@ def main():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
for seed_value in args.seed:
|
for seed_value in args.seed:
|
||||||
# Generate an image for each seed value
|
# 2. Generate an image for each seed value
|
||||||
image = flux.generate_image(
|
image = flux.generate_image(
|
||||||
seed=seed_value,
|
seed=seed_value,
|
||||||
prompt=args.prompt,
|
prompt=args.prompt,
|
||||||
@ -39,7 +39,7 @@ def main():
|
|||||||
init_image_strength=args.init_image_strength,
|
init_image_strength=args.init_image_strength,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
# Save the image
|
# 3. Save the image
|
||||||
image.save(path=args.output.format(seed=seed_value), export_json_metadata=args.metadata)
|
image.save(path=args.output.format(seed=seed_value), export_json_metadata=args.metadata)
|
||||||
except StopImageGenerationException as stop_exc:
|
except StopImageGenerationException as stop_exc:
|
||||||
print(stop_exc)
|
print(stop_exc)
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from mflux import ConfigControlnet, Flux1Controlnet, ModelLookup, StopImageGenerationException
|
from mflux import Config, Flux1Controlnet, ModelLookup, StopImageGenerationException
|
||||||
from mflux.ui.cli.parsers import CommandLineParser
|
from mflux.ui.cli.parsers import CommandLineParser
|
||||||
|
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ def main():
|
|||||||
parser.add_output_arguments()
|
parser.add_output_arguments()
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# Load the model
|
# 1. Load the model
|
||||||
flux = Flux1Controlnet(
|
flux = Flux1Controlnet(
|
||||||
model_config=ModelLookup.from_name(model_name=args.model, base_model=args.base_model),
|
model_config=ModelLookup.from_name(model_name=args.model, base_model=args.base_model),
|
||||||
quantize=args.quantize,
|
quantize=args.quantize,
|
||||||
@ -24,7 +24,7 @@ def main():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
for seed_value in args.seed:
|
for seed_value in args.seed:
|
||||||
# Generate an image for each seed value
|
# 2. Generate an image for each seed value
|
||||||
image = flux.generate_image(
|
image = flux.generate_image(
|
||||||
seed=seed_value,
|
seed=seed_value,
|
||||||
prompt=args.prompt,
|
prompt=args.prompt,
|
||||||
@ -32,7 +32,7 @@ def main():
|
|||||||
controlnet_image_path=args.controlnet_image_path,
|
controlnet_image_path=args.controlnet_image_path,
|
||||||
controlnet_save_canny=args.controlnet_save_canny,
|
controlnet_save_canny=args.controlnet_save_canny,
|
||||||
stepwise_output_dir=Path(args.stepwise_image_output_dir) if args.stepwise_image_output_dir else None,
|
stepwise_output_dir=Path(args.stepwise_image_output_dir) if args.stepwise_image_output_dir else None,
|
||||||
config=ConfigControlnet(
|
config=Config(
|
||||||
num_inference_steps=args.steps,
|
num_inference_steps=args.steps,
|
||||||
height=args.height,
|
height=args.height,
|
||||||
width=args.width,
|
width=args.width,
|
||||||
@ -41,7 +41,7 @@ def main():
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Save the image
|
# 3. Save the image
|
||||||
image.save(path=args.output.format(seed=seed_value), export_json_metadata=args.metadata)
|
image.save(path=args.output.format(seed=seed_value), export_json_metadata=args.metadata)
|
||||||
except StopImageGenerationException as stop_exc:
|
except StopImageGenerationException as stop_exc:
|
||||||
print(stop_exc)
|
print(stop_exc)
|
||||||
|
|||||||
@ -8,25 +8,23 @@ import numpy as np
|
|||||||
import piexif
|
import piexif
|
||||||
import PIL.Image
|
import PIL.Image
|
||||||
|
|
||||||
from mflux.config.config import ConfigControlnet
|
from mflux.config.runtime_config import RuntimeConfig
|
||||||
from mflux.post_processing.generated_image import GeneratedImage
|
from mflux.post_processing.generated_image import GeneratedImage
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
RuntimeConfig: t.TypeAlias = "mflux.config.runtime_config.RuntimeConfig" # noqa: F821
|
|
||||||
|
|
||||||
|
|
||||||
class ImageUtil:
|
class ImageUtil:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def to_image(
|
def to_image(
|
||||||
decoded_latents: mx.array,
|
decoded_latents: mx.array,
|
||||||
|
config: RuntimeConfig,
|
||||||
seed: int,
|
seed: int,
|
||||||
prompt: str,
|
prompt: str,
|
||||||
quantization: int,
|
quantization: int,
|
||||||
generation_time: float,
|
generation_time: float,
|
||||||
lora_paths: list[str],
|
lora_paths: list[str],
|
||||||
lora_scales: list[float],
|
lora_scales: list[float],
|
||||||
config: RuntimeConfig,
|
|
||||||
controlnet_image_path: str | None = None,
|
controlnet_image_path: str | None = None,
|
||||||
init_image_path: str | None = None,
|
init_image_path: str | None = None,
|
||||||
init_image_strength: float | None = None,
|
init_image_strength: float | None = None,
|
||||||
@ -49,7 +47,7 @@ class ImageUtil:
|
|||||||
init_image_path=init_image_path,
|
init_image_path=init_image_path,
|
||||||
init_image_strength=init_image_strength,
|
init_image_strength=init_image_strength,
|
||||||
controlnet_image_path=controlnet_image_path,
|
controlnet_image_path=controlnet_image_path,
|
||||||
controlnet_strength=config.controlnet_strength if isinstance(config.config, ConfigControlnet) else None,
|
controlnet_strength=config.controlnet_strength,
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
@ -40,13 +40,13 @@ class StepwiseHandler:
|
|||||||
stepwise_decoded = self.flux.vae.decode(unpack_latents)
|
stepwise_decoded = self.flux.vae.decode(unpack_latents)
|
||||||
stepwise_img = ImageUtil.to_image(
|
stepwise_img = ImageUtil.to_image(
|
||||||
decoded_latents=stepwise_decoded,
|
decoded_latents=stepwise_decoded,
|
||||||
|
config=self.config,
|
||||||
seed=self.seed,
|
seed=self.seed,
|
||||||
prompt=self.prompt,
|
prompt=self.prompt,
|
||||||
quantization=self.flux.bits,
|
quantization=self.flux.bits,
|
||||||
generation_time=self.time_steps.format_dict["elapsed"],
|
|
||||||
lora_paths=self.flux.lora_paths,
|
lora_paths=self.flux.lora_paths,
|
||||||
lora_scales=self.flux.lora_scales,
|
lora_scales=self.flux.lora_scales,
|
||||||
config=self.config,
|
generation_time=self.time_steps.format_dict["elapsed"],
|
||||||
)
|
)
|
||||||
self.step_wise_images.append(stepwise_img)
|
self.step_wise_images.append(stepwise_img)
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import os
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from mflux import ConfigControlnet, Flux1Controlnet, ModelConfig
|
from mflux import Config, Flux1Controlnet, ModelConfig
|
||||||
from tests.image_generation.helpers.image_generation_test_helper import ImageGeneratorTestHelper
|
from tests.image_generation.helpers.image_generation_test_helper import ImageGeneratorTestHelper
|
||||||
|
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ class ImageGeneratorControlnetTestHelper:
|
|||||||
output=str(output_image_path),
|
output=str(output_image_path),
|
||||||
controlnet_image_path=controlnet_image_path,
|
controlnet_image_path=controlnet_image_path,
|
||||||
controlnet_save_canny=False,
|
controlnet_save_canny=False,
|
||||||
config=ConfigControlnet(
|
config=Config(
|
||||||
num_inference_steps=steps,
|
num_inference_steps=steps,
|
||||||
height=768,
|
height=768,
|
||||||
width=493,
|
width=493,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user