From e97d7dfb9ff6ebbd878ddf5735a1cf0a3414e155 Mon Sep 17 00:00:00 2001 From: Timothy Farrell Date: Sat, 17 Aug 2024 10:33:34 -0500 Subject: [PATCH 1/5] Add CLI args for easier execution --- main.py | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/main.py b/main.py index 5cf39bb..1da111e 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,7 @@ import os import sys +import argparse +import time sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), 'src'))) @@ -7,16 +9,34 @@ from flux_1_schnell.config.config import Config from flux_1_schnell.flux import Flux1Schnell from flux_1_schnell.post_processing.image_util import ImageUtil -flux = Flux1Schnell("black-forest-labs/FLUX.1-schnell") +def main(): + parser = argparse.ArgumentParser(description='Generate an image based on a prompt.') + parser.add_argument('--prompt', type=str, required=True, help='The textual description of the image to generate.') + parser.add_argument('--output', type=str, default="image.png", help='The filename for the output image. Default is "image.png".') + parser.add_argument('--model', type=str, default="black-forest-labs/FLUX.1-schnell", help='The model to use. Default is "black-forest-labs/FLUX.1-schnell".') + parser.add_argument('--seed', type=int, default=0, help='Entropy Seed (Default is time-based random-seed)') + parser.add_argument('--height', type=int, default=1024, help='Image height (Default is 1024)') + parser.add_argument('--width', type=int, default=1024, help='Image width (Default is 1024)') + parser.add_argument('--steps', type=int, default=4, help='Inference Steps') -image = flux.generate_image( - seed=3, - prompt="Luxury food photograph of a birthday cake. In the middle it has three candles shaped like letters spelling the word 'MLX'. It has perfect lighting and a cozy background with big bokeh and shallow depth of field. The mood is a sunset balcony in tuscany. The photo is taken from the side of the cake. The scene is complemented by a warm, inviting light that highlights the textures and colors of the ingredients, giving it an appetizing and elegant look.", - config=Config( - num_inference_steps=2, - height=768, - width=1360, + args = parser.parse_args() + + seed = args.seed or time.time() + + flux = Flux1Schnell(args.model) + + image = flux.generate_image( + seed=args.seed, + prompt=args.prompt, + config=Config( + num_inference_steps=args.steps, + height=args.height, + width=args.width, + ) ) -) -ImageUtil.save_image(image, "image.png") + image.save(args.output) + +if __name__ == '__main__': + main() + From 62c7a9939f88549bedaf2b4dd526a4e7e17aefc4 Mon Sep 17 00:00:00 2001 From: Timothy Farrell Date: Sat, 17 Aug 2024 10:46:22 -0500 Subject: [PATCH 2/5] Remove it from the TODO list. --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 06bebbe..8779659 100644 --- a/README.md +++ b/README.md @@ -135,4 +135,3 @@ Luxury food photograph of an italian Linguine pasta alle vongole dish with lots - FLUX Dev implementation - LoRA adapters -- Command line args \ No newline at end of file From 67f3f8e46c5a8b725d88d142b4ee4918f192e9e9 Mon Sep 17 00:00:00 2001 From: Timothy Farrell Date: Mon, 19 Aug 2024 08:46:39 -0500 Subject: [PATCH 3/5] Update the README to include the (now required) prompt --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8779659..967d43a 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ like [Numpy](https://numpy.org) and [Pillow](https://pypi.org/project/pillow/) f Run the provided [main.py](main.py) ``` -python main.py +python main.py --prompt "luxury food photograph" --steps 2 ``` or make a new separate script like the following From f21a07492945b95c85c762c64afc5fd7320cd159 Mon Sep 17 00:00:00 2001 From: filipstrand Date: Mon, 19 Aug 2024 18:24:52 +0200 Subject: [PATCH 4/5] Save image using util method and update README with command line argument descriptions --- README.md | 25 ++++++++++++++++++++++--- main.py | 7 ++++--- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 967d43a..dca8aef 100644 --- a/README.md +++ b/README.md @@ -37,12 +37,29 @@ like [Numpy](https://numpy.org) and [Pillow](https://pypi.org/project/pillow/) f ``` ### Generating an image -Run the provided [main.py](main.py) +Run the provided [main.py](main.py) by specifying a prompt and some optional arguments like so: + ``` -python main.py --prompt "luxury food photograph" --steps 2 +python main.py --prompt "Luxury food photograph" --steps 2 --seed 2 ``` -or make a new separate script like the following +#### Full list of Command-Line Arguments + +- **`--prompt`** (required, `str`): Text description of the image to generate. + +- **`--output`** (optional, `str`, default: `"image.png"`): Output image filename. + +- **`--model`** (optional, `str`, default: `"black-forest-labs/FLUX.1-schnell"`): Model to use for generation. + +- **`--seed`** (optional, `int`, default: `0`): Seed for random number generation. Default is time-based. + +- **`--height`** (optional, `int`, default: `1024`): Height of the output image in pixels. + +- **`--width`** (optional, `int`, default: `1024`): Width of the output image in pixels. + +- **`--steps`** (optional, `int`, default: `4`): Number of inference steps. + +Or make a new separate script like the following ```python import sys @@ -60,6 +77,8 @@ image = flux.generate_image( prompt="Luxury food photograph of a birthday cake. In the middle it has three candles shaped like letters spelling the word 'MLX'. It has perfect lighting and a cozy background with big bokeh and shallow depth of field. The mood is a sunset balcony in tuscany. The photo is taken from the side of the cake. The scene is complemented by a warm, inviting light that highlights the textures and colors of the ingredients, giving it an appetizing and elegant look.", config=Config( num_inference_steps=2, + height=768, + width=1360, ) ) diff --git a/main.py b/main.py index 1da111e..97b3f39 100644 --- a/main.py +++ b/main.py @@ -9,6 +9,7 @@ from flux_1_schnell.config.config import Config from flux_1_schnell.flux import Flux1Schnell from flux_1_schnell.post_processing.image_util import ImageUtil + def main(): parser = argparse.ArgumentParser(description='Generate an image based on a prompt.') parser.add_argument('--prompt', type=str, required=True, help='The textual description of the image to generate.') @@ -21,7 +22,7 @@ def main(): args = parser.parse_args() - seed = args.seed or time.time() + seed = args.seed or int(time.time()) flux = Flux1Schnell(args.model) @@ -35,8 +36,8 @@ def main(): ) ) - image.save(args.output) + ImageUtil.save_image(image, "image.png") + if __name__ == '__main__': main() - From 801b13266757cdad30bdae9e41004299db7ec6c7 Mon Sep 17 00:00:00 2001 From: filipstrand Date: Mon, 19 Aug 2024 19:19:12 +0200 Subject: [PATCH 5/5] Update readme with latest performance numbers --- README.md | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index dca8aef..d227d18 100644 --- a/README.md +++ b/README.md @@ -87,12 +87,28 @@ ImageUtil.save_image(image, "image.png") If the model is not already downloaded on your machine, it will start the download process and fetch the model weights (~34GB in size for the Schnell model). -Generating a single image (with 2 inference steps, Schnell model) takes between 2 and 3 minutes. This implementation has been tested on two Macbook Pro machines: -- 2021 M1 Pro (32 GB) -- 2023 M2 Max (32 GB) -Update: -On faster machines, [@karpathy](https://gist.github.com/awni/a67d16d50f0f492d94a10418e0592bde?permalink_comment_id=5153531#gistcomment-5153531) and [@awni](https://x.com/awnihannun/status/1823515121827897385) have reported times ~20s and below! +### Image generation speed (updated) + +These numbers are based on the Schnell model, with the configuration provided in the code snippet below. +To time your machine, run the following: +``` +time python main.py \ +--prompt "Luxury food photograph" \ +--steps 2 \ +--seed 2 \ +--height 1024 \ +--width 1024 +``` + +| Device | User | Reported Time | +|--------------------|----------------------------------------------------------------------------------------------------------------------------|---------------| +| M3 Max | [@karpathy](https://gist.github.com/awni/a67d16d50f0f492d94a10418e0592bde?permalink_comment_id=5153531#gistcomment-5153531) | ~20s | +| M2 Ultra | [@awni](https://x.com/awnihannun/status/1823515121827897385) | <15s | +| 2023 M2 Max (96GB) | [@explorigin](https://github.com/filipstrand/mflux/issues/6) | ~25s | +| 2021 M1 Pro (16GB) | [@qw-in](https://github.com/filipstrand/mflux/issues/7) | ~175s | +| 2021 M1 Pro (32GB) | @filipstrand | ~160s | +| 2023 M2 Max (32GB) | @filipstrand | ~70s | ### Equivalent to Diffusers implementation