Spaces:
Runtime error
Runtime error
| """FLUX.2 [dev] 4-bit studio — text-to-image and multi-reference editing, self-contained. | |
| Runs the pre-quantized `diffusers/FLUX.2-dev-bnb-4bit` checkpoint: full dev quality at | |
| about a fifth of the footprint, with the text encoder loaded INSIDE this Space. That | |
| last part matters — the public dev demo delegates its text encoder to a separate Space, | |
| so it breaks for good whenever that other Space goes away. | |
| The /infer signature mirrors the common FLUX.2 Space API, so existing clients only need | |
| to change the space id. | |
| """ | |
| import os | |
| import random | |
| import gradio as gr | |
| import numpy as np | |
| import spaces | |
| import torch | |
| from diffusers import Flux2Pipeline | |
| from PIL import Image | |
| MODEL_ID = os.environ.get("FLUX2_MODEL", "diffusers/FLUX.2-dev-bnb-4bit") | |
| MAX_SEED = np.iinfo(np.int32).max | |
| MAX_SIDE = 1536 | |
| pipe = Flux2Pipeline.from_pretrained( | |
| MODEL_ID, | |
| torch_dtype=torch.bfloat16, | |
| device_map=None, # let the offload hook place things, not the loader | |
| ) | |
| pipe.enable_model_cpu_offload() # 4-bit weights still want room to breathe | |
| def _duration(prompt, image_list, seed, width, height, num_inference_steps, guidance_scale): | |
| """ZeroGPU reserves the slot before the call and passes it the same arguments, so | |
| this signature must mirror _run's exactly.""" | |
| n = 1 + 0.6 * len(image_list or []) | |
| return int(min(300, max(90, int(num_inference_steps) * 2.4 * n + 40))) | |
| def _run(prompt, image_list, seed, width, height, num_inference_steps, guidance_scale): | |
| generator = torch.Generator(device="cuda").manual_seed(int(seed)) | |
| kwargs = dict(prompt=prompt, width=int(width), height=int(height), | |
| num_inference_steps=int(num_inference_steps), | |
| guidance_scale=float(guidance_scale), generator=generator) | |
| if image_list: | |
| kwargs["image"] = image_list | |
| return pipe(**kwargs).images[0] | |
| def infer(prompt, input_images, seed=0, randomize_seed=False, width=1024, height=1024, | |
| num_inference_steps=28, guidance_scale=4.0, prompt_upsampling=False, | |
| progress=gr.Progress(track_tqdm=True)): | |
| if randomize_seed: | |
| seed = random.randint(0, MAX_SEED) | |
| images = [] | |
| for item in (input_images or []): | |
| path = item[0] if isinstance(item, (list, tuple)) else item | |
| if isinstance(path, dict): | |
| path = path.get("image") or path.get("path") or path.get("name") | |
| if path: | |
| im = Image.open(path).convert("RGB") | |
| im.thumbnail((MAX_SIDE, MAX_SIDE)) | |
| images.append(im) | |
| width = min(int(width), MAX_SIDE) | |
| height = min(int(height), MAX_SIDE) | |
| out = _run(prompt, images, seed, width, height, num_inference_steps, guidance_scale) | |
| return out, seed | |
| with gr.Blocks(title="FLUX.2 dev 4-bit studio") as demo: | |
| gr.Markdown("## FLUX.2 [dev] 4-bit studio\nText-to-image and multi-reference editing. " | |
| "Self-contained: the text encoder lives in this Space.") | |
| with gr.Row(): | |
| with gr.Column(): | |
| prompt = gr.Textbox(label="Prompt", lines=4) | |
| input_images = gr.Gallery(label="Reference images (optional)", type="filepath", | |
| columns=4, height=200) | |
| run = gr.Button("Generate", variant="primary") | |
| with gr.Accordion("Settings", open=False): | |
| seed = gr.Slider(0, MAX_SEED, value=0, step=1, label="Seed") | |
| randomize_seed = gr.Checkbox(True, label="Randomize seed") | |
| width = gr.Slider(256, MAX_SIDE, value=1024, step=32, label="Width") | |
| height = gr.Slider(256, MAX_SIDE, value=1024, step=32, label="Height") | |
| num_inference_steps = gr.Slider(4, 50, value=28, step=1, label="Steps") | |
| guidance_scale = gr.Slider(1.0, 10.0, value=4.0, step=0.1, label="Guidance") | |
| prompt_upsampling = gr.Checkbox(False, label="Prompt upsampling (unused)") | |
| with gr.Column(): | |
| result = gr.Image(label="Result", type="pil") | |
| used_seed = gr.Number(label="Seed used") | |
| run.click(infer, | |
| inputs=[prompt, input_images, seed, randomize_seed, width, height, | |
| num_inference_steps, guidance_scale, prompt_upsampling], | |
| outputs=[result, used_seed], api_name="infer") | |
| demo.queue().launch(show_error=True) | |