Deadmon commited on
Commit
22cf3c8
·
verified ·
1 Parent(s): c2ba9e0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -85
app.py CHANGED
@@ -6,114 +6,85 @@ from PIL import Image
6
  from einops import rearrange
7
  import requests
8
  import spaces
9
- from huggingface_hub import login
10
- from gradio_imageslider import ImageSlider # Import ImageSlider
11
-
12
- from image_datasets.canny_dataset import canny_processor, c_crop
13
- from src.flux.sampling import denoise_controlnet, get_noise, get_schedule, prepare, unpack
14
- from src.flux.util import load_ae, load_clip, load_t5, load_flow_model, load_controlnet, load_safetensors
15
-
16
- # Download and load the ControlNet model
17
- model_url = "https://huggingface.co/XLabs-AI/flux-controlnet-canny-v3/resolve/main/flux-canny-controlnet-v3.safetensors?download=true"
18
- model_path = "./flux-canny-controlnet-v3.safetensors"
19
- if not os.path.exists(model_path):
20
- response = requests.get(model_url)
21
- with open(model_path, 'wb') as f:
22
- f.write(response.content)
23
-
24
- # Source: https://github.com/XLabs-AI/x-flux.git
25
- name = "flux-dev"
26
- device = torch.device("cuda")
27
- offload = False
28
- is_schnell = name == "flux-schnell"
29
-
30
- def preprocess_image(image, target_width, target_height, crop=True):
31
- if crop:
32
- image = c_crop(image) # Crop the image to square
33
- original_width, original_height = image.size
34
-
35
- # Resize to match the target size without stretching
36
- scale = max(target_width / original_width, target_height / original_height)
37
- resized_width = int(scale * original_width)
38
- resized_height = int(scale * original_height)
39
-
40
- image = image.resize((resized_width, resized_height), Image.LANCZOS)
41
-
42
- # Center crop to match the target dimensions
43
- left = (resized_width - target_width) // 2
44
- top = (resized_height - target_height) // 2
45
- image = image.crop((left, top, left + target_width, top + target_height))
46
- else:
47
- image = image.resize((target_width, target_height), Image.LANCZOS)
48
-
49
- return image
50
-
51
- def preprocess_canny_image(image, target_width, target_height, crop=True):
52
- image = preprocess_image(image, target_width, target_height, crop=crop)
53
- image = canny_processor(image)
54
  return image
55
 
56
  @spaces.GPU(duration=120)
57
- def generate_image(prompt, control_image, num_steps=50, guidance=4, width=512, height=512, seed=42, random_seed=False):
58
  if random_seed:
59
  seed = np.random.randint(0, 10000)
60
 
61
- if not os.path.isdir("./controlnet_results/"):
62
- os.makedirs("./controlnet_results/")
63
-
64
- torch_device = torch.device("cuda")
65
 
66
- torch.cuda.empty_cache() # Clear GPU cache
 
67
 
68
- model = load_flow_model(name, device=torch_device)
69
- t5 = load_t5(torch_device, max_length=256 if is_schnell else 512)
70
- clip = load_clip(torch_device)
71
- ae = load_ae(name, device=torch_device)
72
- controlnet = load_controlnet(name, torch_device).to(torch_device).to(torch.bfloat16)
73
-
74
- checkpoint = load_safetensors(model_path)
75
- controlnet.load_state_dict(checkpoint, strict=False)
76
-
77
- width = 16 * width // 16
78
- height = 16 * height // 16
79
- timesteps = get_schedule(num_steps, (width // 8) * (height // 8) // (16 * 16), shift=(not is_schnell))
80
 
81
- processed_input = preprocess_image(control_image, width, height)
82
- canny_processed = preprocess_canny_image(control_image, width, height)
83
- controlnet_cond = torch.from_numpy((np.array(canny_processed) / 127.5) - 1)
84
- controlnet_cond = controlnet_cond.permute(2, 0, 1).unsqueeze(0).to(torch.bfloat16).to(torch_device)
85
 
86
- torch.manual_seed(seed)
87
  with torch.no_grad():
88
- x = get_noise(1, height, width, device=torch_device, dtype=torch.bfloat16, seed=seed)
89
- inp_cond = prepare(t5=t5, clip=clip, img=x, prompt=prompt)
90
-
91
- x = denoise_controlnet(model, **inp_cond, controlnet=controlnet, timesteps=timesteps, guidance=guidance, controlnet_cond=controlnet_cond)
92
-
93
- x = unpack(x.float(), height, width)
94
- x = ae.decode(x)
95
-
96
- x1 = x.clamp(-1, 1)
97
- x1 = rearrange(x1[-1], "c h w -> h w c")
98
- output_img = Image.fromarray((127.5 * (x1 + 1.0)).cpu().byte().numpy())
99
 
100
- return [processed_input, output_img] # Return both images for slider
101
 
 
102
  interface = gr.Interface(
103
  fn=generate_image,
104
  inputs=[
105
  gr.Textbox(label="Prompt"),
106
  gr.Image(type="pil", label="Control Image"),
107
- gr.Slider(step=1, minimum=1, maximum=64, value=28, label="Num Steps"),
108
- gr.Slider(minimum=0.1, maximum=10, value=4, label="Guidance"),
 
 
109
  gr.Slider(minimum=128, maximum=1024, step=128, value=512, label="Width"),
110
  gr.Slider(minimum=128, maximum=1024, step=128, value=512, label="Height"),
111
  gr.Number(value=42, label="Seed"),
112
  gr.Checkbox(label="Random Seed")
113
  ],
114
- outputs=ImageSlider(label="Before / After"), # Use ImageSlider as the output
115
- title="FLUX.1 Controlnet Canny",
116
- description="Generate images using ControlNet and a text prompt.\n[[non-commercial license, Flux.1 Dev](https://huggingface.co/black-forest-labs/FLUX.1-dev/blob/main/LICENSE.md)]"
117
  )
118
 
119
  if __name__ == "__main__":
 
6
  from einops import rearrange
7
  import requests
8
  import spaces
9
+ from diffusers.utils import load_image
10
+ from diffusers import FluxControlNetPipeline, FluxControlNetModel
11
+ from gradio_imageslider import ImageSlider
12
+
13
+ # Pretrained model paths
14
+ base_model = 'black-forest-labs/FLUX.1-dev'
15
+ controlnet_model = 'InstantX/FLUX.1-dev-Controlnet-Union'
16
+
17
+ # Load the ControlNet and pipeline models
18
+ controlnet = FluxControlNetModel.from_pretrained(controlnet_model, torch_dtype=torch.bfloat16)
19
+ pipe = FluxControlNetPipeline.from_pretrained(base_model, controlnet=controlnet, torch_dtype=torch.bfloat16)
20
+ pipe.to("cuda")
21
+
22
+ # Define control modes
23
+ CONTROL_MODES = {
24
+ 0: "Canny",
25
+ 1: "Tile",
26
+ 2: "Depth",
27
+ 3: "Blur",
28
+ 4: "Pose",
29
+ 5: "Gray (Low)",
30
+ 6: "LQ"
31
+ }
32
+
33
+ def preprocess_image(image, target_width, target_height):
34
+ image = image.resize((target_width, target_height), Image.LANCZOS)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  return image
36
 
37
  @spaces.GPU(duration=120)
38
+ def generate_image(prompt, control_image, control_mode, controlnet_conditioning_scale, num_steps, guidance, width, height, seed, random_seed):
39
  if random_seed:
40
  seed = np.random.randint(0, 10000)
41
 
42
+ # Ensure width and height are multiples of 16
43
+ width = 16 * (width // 16)
44
+ height = 16 * (height // 16)
 
45
 
46
+ # Set the seed for reproducibility
47
+ torch.manual_seed(seed)
48
 
49
+ # Preprocess control image
50
+ control_image = preprocess_image(control_image, width, height)
 
 
 
 
 
 
 
 
 
 
51
 
52
+ # Ensure control_mode is an integer
53
+ control_mode_index = int(control_mode)
 
 
54
 
55
+ # Generate the image with the selected control mode and other parameters
56
  with torch.no_grad():
57
+ image = pipe(
58
+ prompt,
59
+ control_image=control_image,
60
+ control_mode=control_mode_index, # Pass control mode as an integer
61
+ width=width,
62
+ height=height,
63
+ controlnet_conditioning_scale=controlnet_conditioning_scale,
64
+ num_inference_steps=num_steps,
65
+ guidance_scale=guidance
66
+ ).images[0]
 
67
 
68
+ return image
69
 
70
+ # Define the Gradio interface
71
  interface = gr.Interface(
72
  fn=generate_image,
73
  inputs=[
74
  gr.Textbox(label="Prompt"),
75
  gr.Image(type="pil", label="Control Image"),
76
+ gr.Dropdown(choices=[(i, name) for i, name in CONTROL_MODES.items()], label="Control Mode", value=0), # Correct value and format for dropdown
77
+ gr.Slider(minimum=0.1, maximum=1.0, step=0.1, value=0.5, label="ControlNet Conditioning Scale"),
78
+ gr.Slider(step=1, minimum=1, maximum=64, value=24, label="Num Steps"),
79
+ gr.Slider(minimum=0.1, maximum=10, value=3.5, label="Guidance"),
80
  gr.Slider(minimum=128, maximum=1024, step=128, value=512, label="Width"),
81
  gr.Slider(minimum=128, maximum=1024, step=128, value=512, label="Height"),
82
  gr.Number(value=42, label="Seed"),
83
  gr.Checkbox(label="Random Seed")
84
  ],
85
+ outputs=ImageSlider(label="Generated Image"),
86
+ title="FLUX.1 Controlnet with Multiple Modes",
87
+ description="Generate images using ControlNet and a text prompt with adjustable control modes."
88
  )
89
 
90
  if __name__ == "__main__":