Deadmon commited on
Commit
7f15638
·
verified ·
1 Parent(s): b48369c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +33 -69
app.py CHANGED
@@ -4,47 +4,23 @@ import gradio as gr
4
  import numpy as np
5
  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
- model, ae, t5, clip, controlnet = None, None, None, None, None
31
-
32
- def load_models():
33
- global model, ae, t5, clip, controlnet
34
- t5 = load_t5(device, max_length=256 if is_schnell else 512)
35
- clip = load_clip(device)
36
- model = load_flow_model(name, device=device)
37
- ae = load_ae(name, device=device)
38
- controlnet = load_controlnet(name, device).to(device).to(torch.bfloat16)
39
 
40
- checkpoint = load_safetensors(model_path)
41
- controlnet.load_state_dict(checkpoint, strict=False)
42
-
43
- load_models()
44
 
45
  def preprocess_image(image, target_width, target_height, crop=True):
46
  if crop:
47
- image = c_crop(image) # Crop the image to square
48
  original_width, original_height = image.size
49
 
50
  # Resize to match the target size without stretching
@@ -65,61 +41,50 @@ def preprocess_image(image, target_width, target_height, crop=True):
65
 
66
  def preprocess_canny_image(image, target_width, target_height, crop=True):
67
  image = preprocess_image(image, target_width, target_height, crop=crop)
68
- image = canny_processor(image)
 
 
69
  return image
70
 
71
- @spaces.GPU(duration=120)
72
- def generate_image(prompt, control_image, num_steps=50, guidance=4, width=512, height=512, seed=42, random_seed=False):
73
  if random_seed:
74
  seed = np.random.randint(0, 10000)
75
 
76
  if not os.path.isdir("./controlnet_results/"):
77
  os.makedirs("./controlnet_results/")
78
 
79
- torch_device = torch.device("cuda")
80
-
81
- model.to(torch_device)
82
- t5.to(torch_device)
83
- clip.to(torch_device)
84
- ae.to(torch_device)
85
- controlnet.to(torch_device)
86
-
87
- width = 16 * width // 16
88
- height = 16 * height // 16
89
- timesteps = get_schedule(num_steps, (width // 8) * (height // 8) // (16 * 16), shift=(not is_schnell))
90
-
91
- processed_input = preprocess_image(control_image, width, height)
92
- canny_processed = preprocess_canny_image(control_image, width, height)
93
- controlnet_cond = torch.from_numpy((np.array(canny_processed) / 127.5) - 1)
94
- controlnet_cond = controlnet_cond.permute(2, 0, 1).unsqueeze(0).to(torch.bfloat16).to(torch_device)
95
-
96
  torch.manual_seed(seed)
97
- with torch.no_grad():
98
- x = get_noise(1, height, width, device=torch_device, dtype=torch.bfloat16, seed=seed)
99
- inp_cond = prepare(t5=t5, clip=clip, img=x, prompt=prompt)
100
 
101
- x = denoise_controlnet(model, **inp_cond, controlnet=controlnet, timesteps=timesteps, guidance=guidance, controlnet_cond=controlnet_cond)
102
-
103
- x = unpack(x.float(), height, width)
104
- x = ae.decode(x)
105
-
106
- x1 = x.clamp(-1, 1)
107
- x1 = rearrange(x1[-1], "c h w -> h w c")
108
- output_img = Image.fromarray((127.5 * (x1 + 1.0)).cpu().byte().numpy())
109
 
110
- return [processed_input, output_img] # Return both images for slider
 
 
 
 
 
 
 
 
 
 
 
 
111
 
112
  interface = gr.Interface(
113
  fn=generate_image,
114
  inputs=[
115
  gr.Textbox(label="Prompt"),
116
  gr.Image(type="pil", label="Control Image"),
117
- gr.Slider(step=1, minimum=1, maximum=64, value=28, label="Num Steps"),
118
- gr.Slider(minimum=0.1, maximum=10, value=4, label="Guidance"),
119
  gr.Slider(minimum=128, maximum=2048, step=128, value=1024, label="Width"),
120
  gr.Slider(minimum=128, maximum=2048, step=128, value=1024, label="Height"),
121
  gr.Number(value=42, label="Seed"),
122
- gr.Checkbox(label="Random Seed")
 
123
  ],
124
  outputs=ImageSlider(label="Before / After"), # Use ImageSlider as the output
125
  title="FLUX.1 Controlnet Canny",
@@ -128,4 +93,3 @@ interface = gr.Interface(
128
 
129
  if __name__ == "__main__":
130
  interface.launch()
131
-
 
4
  import numpy as np
5
  from PIL import Image
6
  from einops import rearrange
7
+ from diffusers import FluxControlNetPipeline, FluxControlNetModel
8
+ from diffusers.utils import load_image
 
9
  from gradio_imageslider import ImageSlider # Import ImageSlider
10
 
11
+ # Load the new ControlNet model
12
+ base_model = 'black-forest-labs/FLUX.1-dev'
13
+ controlnet_model = 'InstantX/FLUX.1-dev-Controlnet-Union'
14
 
 
 
 
 
 
 
 
 
 
 
15
  device = torch.device("cuda")
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
+ controlnet = FluxControlNetModel.from_pretrained(controlnet_model, torch_dtype=torch.bfloat16)
18
+ pipe = FluxControlNetPipeline.from_pretrained(base_model, controlnet=controlnet, torch_dtype=torch.bfloat16)
19
+ pipe.to(device)
 
20
 
21
  def preprocess_image(image, target_width, target_height, crop=True):
22
  if crop:
23
+ image = image.crop((0, 0, min(image.size), min(image.size))) # Crop the image to square
24
  original_width, original_height = image.size
25
 
26
  # Resize to match the target size without stretching
 
41
 
42
  def preprocess_canny_image(image, target_width, target_height, crop=True):
43
  image = preprocess_image(image, target_width, target_height, crop=crop)
44
+ image = np.array(image.convert('L')) # Convert to grayscale for Canny processing
45
+ image = cv2.Canny(image, 100, 200) # Apply Canny edge detection
46
+ image = Image.fromarray(image)
47
  return image
48
 
49
+ def generate_image(prompt, control_image, num_steps=24, guidance=3.5, width=512, height=512, seed=42, random_seed=False, control_mode=0):
 
50
  if random_seed:
51
  seed = np.random.randint(0, 10000)
52
 
53
  if not os.path.isdir("./controlnet_results/"):
54
  os.makedirs("./controlnet_results/")
55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  torch.manual_seed(seed)
 
 
 
57
 
58
+ control_image = preprocess_canny_image(control_image, width, height) # Preprocess the control image for Canny mode
59
+
60
+ controlnet_conditioning_scale = 0.5 # ControlNet conditioning scale
 
 
 
 
 
61
 
62
+ # Generate the image using the pipeline
63
+ image = pipe(
64
+ prompt,
65
+ control_image=control_image,
66
+ control_mode=control_mode,
67
+ width=width,
68
+ height=height,
69
+ controlnet_conditioning_scale=controlnet_conditioning_scale,
70
+ num_inference_steps=num_steps,
71
+ guidance_scale=guidance,
72
+ ).images[0]
73
+
74
+ return [control_image, image] # Return both images for slider
75
 
76
  interface = gr.Interface(
77
  fn=generate_image,
78
  inputs=[
79
  gr.Textbox(label="Prompt"),
80
  gr.Image(type="pil", label="Control Image"),
81
+ gr.Slider(step=1, minimum=1, maximum=64, value=24, label="Num Steps"),
82
+ gr.Slider(minimum=0.1, maximum=10, value=3.5, label="Guidance"),
83
  gr.Slider(minimum=128, maximum=2048, step=128, value=1024, label="Width"),
84
  gr.Slider(minimum=128, maximum=2048, step=128, value=1024, label="Height"),
85
  gr.Number(value=42, label="Seed"),
86
+ gr.Checkbox(label="Random Seed"),
87
+ gr.Radio(choices=[0, 1, 2, 3, 4, 5, 6], value=0, label="Control Mode")
88
  ],
89
  outputs=ImageSlider(label="Before / After"), # Use ImageSlider as the output
90
  title="FLUX.1 Controlnet Canny",
 
93
 
94
  if __name__ == "__main__":
95
  interface.launch()