61 lines
2.0 KiB
Python
61 lines
2.0 KiB
Python
from pathlib import Path
|
|
|
|
import mlx.core as mx
|
|
import tqdm
|
|
|
|
from mflux.config.runtime_config import RuntimeConfig
|
|
from mflux.post_processing.array_util import ArrayUtil
|
|
from mflux.post_processing.image_util import ImageUtil
|
|
|
|
|
|
class StepwiseHandler:
|
|
def __init__(
|
|
self,
|
|
flux,
|
|
config: RuntimeConfig,
|
|
seed: int,
|
|
prompt: str,
|
|
time_steps: tqdm.std.tqdm,
|
|
output_dir: Path | None = None,
|
|
):
|
|
self.flux = flux
|
|
self.config = config
|
|
self.seed = seed
|
|
self.prompt = prompt
|
|
self.output_dir = output_dir
|
|
self.time_steps = time_steps
|
|
self.step_wise_images = []
|
|
|
|
if self.output_dir:
|
|
self.output_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
def save_composite(self):
|
|
if self.step_wise_images:
|
|
composite_img = ImageUtil.to_composite_image(self.step_wise_images)
|
|
composite_img.save(self.output_dir / f"seed_{self.seed}_composite.png")
|
|
|
|
def process_step(self, gen_step: int, latents: mx.array):
|
|
if self.output_dir:
|
|
unpack_latents = ArrayUtil.unpack_latents(latents=latents, height=self.config.height, width=self.config.width) # fmt: off
|
|
stepwise_decoded = self.flux.vae.decode(unpack_latents)
|
|
stepwise_img = ImageUtil.to_image(
|
|
decoded_latents=stepwise_decoded,
|
|
seed=self.seed,
|
|
prompt=self.prompt,
|
|
quantization=self.flux.bits,
|
|
generation_time=self.time_steps.format_dict["elapsed"],
|
|
lora_paths=self.flux.lora_paths,
|
|
lora_scales=self.flux.lora_scales,
|
|
config=self.config,
|
|
)
|
|
self.step_wise_images.append(stepwise_img)
|
|
|
|
stepwise_img.save(
|
|
path=self.output_dir / f"seed_{self.seed}_step{gen_step}of{len(self.time_steps)}.png",
|
|
export_json_metadata=False,
|
|
)
|
|
self.save_composite()
|
|
|
|
def handle_interruption(self):
|
|
self.save_composite()
|