DamarJati commited on
Commit
0400b71
1 Parent(s): 45a6a68

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +108 -0
app.py ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import torch
3
+ 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
+
11
+ hf_token = os.getenv("HF_TOKEN")
12
+ # Login to Hugging Face
13
+ login(token=hf_token)
14
+
15
+ from image_datasets.canny_dataset import canny_processor, c_crop
16
+ from src.flux.sampling import denoise_controlnet, get_noise, get_schedule, prepare, unpack
17
+ from src.flux.util import load_ae, load_clip, load_t5, load_flow_model, load_controlnet, load_safetensors
18
+
19
+ # Download and load the ControlNet model
20
+ model_url = "https://huggingface.co/XLabs-AI/flux-controlnet-canny/resolve/main/controlnet.safetensors?download=true"
21
+ model_path = "./controlnet.safetensors"
22
+ if not os.path.exists(model_path):
23
+ response = requests.get(model_url)
24
+ with open(model_path, 'wb') as f:
25
+ f.write(response.content)
26
+
27
+ # https://github.com/XLabs-AI/x-flux.git
28
+ name = "flux-dev"
29
+ device = torch.device("cuda")
30
+ offload = False
31
+ is_schnell = name == "flux-schnell"
32
+
33
+ model, ae, t5, clip, controlnet = None, None, None, None, None
34
+
35
+ def load_models():
36
+ global model, ae, t5, clip, controlnet
37
+ t5 = load_t5(device, max_length=256 if is_schnell else 512)
38
+ clip = load_clip(device)
39
+ model = load_flow_model(name, device=device)
40
+ ae = load_ae(name, device=device)
41
+ controlnet = load_controlnet(name, device).to(device).to(torch.bfloat16)
42
+
43
+ checkpoint = load_safetensors(model_path)
44
+ controlnet.load_state_dict(checkpoint, strict=False)
45
+
46
+ load_models()
47
+
48
+ def preprocess_canny_image(image, width=1024, height=1024):
49
+ image = c_crop(image)
50
+ image = image.resize((width, height))
51
+ image = canny_processor(image)
52
+ return image
53
+
54
+ @spaces.GPU()
55
+ def generate_image(prompt, control_image, num_steps=50, guidance=4, width=512, height=512, seed=42):
56
+ if not os.path.isdir("./controlnet_results/"):
57
+ os.makedirs("./controlnet_results/")
58
+
59
+ torch_device = torch.device("cuda")
60
+
61
+ model.to(torch_device)
62
+ t5.to(torch_device)
63
+ clip.to(torch_device)
64
+ ae.to(torch_device)
65
+ controlnet.to(torch_device)
66
+
67
+ width = 16 * width // 16
68
+ height = 16 * height // 16
69
+ timesteps = get_schedule(num_steps, (width // 8) * (height // 8) // (16 * 16), shift=(not is_schnell))
70
+
71
+ canny_processed = preprocess_canny_image(control_image, width, height)
72
+ controlnet_cond = torch.from_numpy((np.array(canny_processed) / 127.5) - 1)
73
+ controlnet_cond = controlnet_cond.permute(2, 0, 1).unsqueeze(0).to(torch.bfloat16).to(torch_device)
74
+
75
+ torch.manual_seed(seed)
76
+ with torch.no_grad():
77
+ x = get_noise(1, height, width, device=torch_device, dtype=torch.bfloat16, seed=seed)
78
+ inp_cond = prepare(t5=t5, clip=clip, img=x, prompt=prompt)
79
+
80
+ x = denoise_controlnet(model, **inp_cond, controlnet=controlnet, timesteps=timesteps, guidance=guidance, controlnet_cond=controlnet_cond)
81
+
82
+ x = unpack(x.float(), height, width)
83
+ x = ae.decode(x)
84
+
85
+ x1 = x.clamp(-1, 1)
86
+ x1 = rearrange(x1[-1], "c h w -> h w c")
87
+ output_img = Image.fromarray((127.5 * (x1 + 1.0)).cpu().byte().numpy())
88
+
89
+ return output_img
90
+
91
+ interface = gr.Interface(
92
+ fn=generate_image,
93
+ inputs=[
94
+ gr.Textbox(label="Prompt"),
95
+ gr.Image(type="pil", label="Control Image"),
96
+ gr.Slider(step=1, minimum=1, maximum=64, value=28, label="Num Steps"),
97
+ gr.Slider(minimum=0.1, maximum=10, value=4, label="Guidance"),
98
+ gr.Slider(minimum=128, maximum=2048, step=128, value=1024, label="Width"),
99
+ gr.Slider(minimum=128, maximum=2048, step=128, value=1024, label="Height"),
100
+ gr.Number(value=42, label="Seed")
101
+ ],
102
+ outputs=gr.Image(type="pil", label="Generated Image"),
103
+ title="FLUX.1 Controlnet Cany",
104
+ 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)]"
105
+ )
106
+
107
+ if __name__ == "__main__":
108
+ interface.launch()