Files changed (5) hide show
  1. README.md +6 -6
  2. app.py +86 -174
  3. demo.py +0 -199
  4. live_preview_helpers.py +0 -166
  5. requirements.txt +4 -8
README.md CHANGED
@@ -1,14 +1,14 @@
1
  ---
2
- title: FLUX.Dev LoRA
3
- emoji: 💻
4
- colorFrom: blue
5
- colorTo: blue
6
  sdk: gradio
7
- sdk_version: 5.50.0
8
  app_file: app.py
9
  pinned: true
10
  license: mit
11
- short_description: FLUX.1-Dev Text to Image with LoRA
12
  ---
13
 
14
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: FLUX.Dev LORA Serverless
3
+ emoji: 🔥
4
+ colorFrom: pink
5
+ colorTo: purple
6
  sdk: gradio
7
+ sdk_version: 4.43.0
8
  app_file: app.py
9
  pinned: true
10
  license: mit
11
+ short_description: FLUX.1-Dev on serverless inference, no GPU required
12
  ---
13
 
14
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py CHANGED
@@ -1,199 +1,111 @@
1
  import gradio as gr
2
- import numpy as np
 
3
  import random
4
- import spaces
5
- import torch
6
- from diffusers import DiffusionPipeline, FlowMatchEulerDiscreteScheduler, AutoencoderTiny, AutoencoderKL
7
- # from para_attn.first_block_cache.diffusers_adapters import apply_cache_on_pipe
8
- from transformers import CLIPTextModel, CLIPTokenizer,T5EncoderModel, T5TokenizerFast
9
- from live_preview_helpers import calculate_shift, retrieve_timesteps, flux_pipe_call_that_returns_an_iterable_of_images
10
- import multiprocessing as mp
11
-
12
  import os
13
- import requests
14
- import tempfile
15
- import shutil
16
- from urllib.parse import urlparse
17
-
18
- dtype = torch.bfloat16
19
- device = "cuda" if torch.cuda.is_available() else "cpu"
20
- #black-forest-labs/FLUX.1-Krea-dev
21
- taef1 = AutoencoderTiny.from_pretrained("madebyollin/taef1", torch_dtype=dtype).to(device)
22
- good_vae = AutoencoderKL.from_pretrained("black-forest-labs/FLUX.1-dev", subfolder="vae", torch_dtype=dtype).to(device)
23
- pipe = DiffusionPipeline.from_pretrained("black-forest-labs/FLUX.1-dev", torch_dtype=dtype, vae=taef1).to(device)
24
- # srpo_128_base_oficial_model_fp16.safetensors
25
- # pipe.load_lora_weights('Alissonerdx/flux.1-dev-SRPO-LoRas', weight_name='srpo_16_base_oficial_model_fp16.safetensors')
26
- # pipe.fuse_lora()
27
- torch.cuda.empty_cache()
28
-
29
- MAX_SEED = np.iinfo(np.int32).max
30
- MAX_IMAGE_SIZE = 2048
31
-
32
- pipe.flux_pipe_call_that_returns_an_iterable_of_images = flux_pipe_call_that_returns_an_iterable_of_images.__get__(pipe)
33
-
34
- def load_lora_auto(pipe, lora_input):
35
- lora_input = lora_input.strip()
36
- if not lora_input:
37
- return
38
-
39
- # If it's just an ID like "author/model"
40
- if "/" in lora_input and not lora_input.startswith("http"):
41
- pipe.load_lora_weights(lora_input)
42
- return
43
-
44
- if lora_input.startswith("http"):
45
- url = lora_input
46
-
47
- # Repo page (no blob/resolve)
48
- if "huggingface.co" in url and "/blob/" not in url and "/resolve/" not in url:
49
- repo_id = urlparse(url).path.strip("/")
50
- pipe.load_lora_weights(repo_id)
51
- return
52
-
53
- # Blob link → convert to resolve link
54
- if "/blob/" in url:
55
- url = url.replace("/blob/", "/resolve/")
56
-
57
- # Download direct file
58
- tmp_dir = tempfile.mkdtemp()
59
- local_path = os.path.join(tmp_dir, os.path.basename(urlparse(url).path))
60
-
61
- try:
62
- print(f"Downloading LoRA from {url}...")
63
- resp = requests.get(url, stream=True)
64
- resp.raise_for_status()
65
- with open(local_path, "wb") as f:
66
- for chunk in resp.iter_content(chunk_size=8192):
67
- f.write(chunk)
68
- print(f"Saved LoRA to {local_path}")
69
- pipe.load_lora_weights(local_path)
70
- finally:
71
- shutil.rmtree(tmp_dir, ignore_errors=True)
72
-
73
- @spaces.GPU(duration=30)
74
- def infer(prompt, seed=42, randomize_seed=False, width=1024, height=1024, guidance_scale=3.5, num_inference_steps=28, lora_id=None, lora_scale=0.95, progress=gr.Progress(track_tqdm=True)):
75
- if randomize_seed:
76
- seed = random.randint(0, MAX_SEED)
77
- generator = torch.Generator().manual_seed(seed)
78
 
 
 
 
79
 
80
- # for img in pipe.flux_pipe_call_that_returns_an_iterable_of_images(
81
- # prompt=prompt,
82
- # guidance_scale=guidance_scale,
83
- # num_inference_steps=num_inference_steps,
84
- # width=width,
85
- # height=height,
86
- # generator=generator,
87
- # output_type="pil",
88
- # good_vae=good_vae,
89
- # ):
90
- # yield img, seed
91
-
92
- # Handle LoRA loading
93
- # Load LoRA weights and prepare joint_attention_kwargs
94
- if lora_id and lora_id.strip() != "":
95
- pipe.unload_lora_weights()
96
- # pipe.load_lora_weights(lora_id.strip())
97
- load_lora_auto(pipe, lora_id.strip())
98
- joint_attention_kwargs = {"scale": lora_scale}
99
- else:
100
- joint_attention_kwargs = None
101
-
102
- # apply_cache_on_pipe(
103
- # pipe,
104
- # # residual_diff_threshold=0.2,
105
- # )
106
 
107
- try:
108
- # Call the custom pipeline function with the correct keyword argument
109
- for img in pipe.flux_pipe_call_that_returns_an_iterable_of_images(
110
- prompt=prompt,
111
- guidance_scale=guidance_scale,
112
- num_inference_steps=num_inference_steps,
113
- width=width,
114
- height=height,
115
- generator=generator,
116
- output_type="pil",
117
- good_vae=good_vae, # Assuming good_vae is defined elsewhere
118
- joint_attention_kwargs=joint_attention_kwargs, # Fixed parameter name
119
- ):
120
- yield img, seed
121
- finally:
122
- # Unload LoRA weights if they were loaded
123
- if lora_id:
124
- pipe.unload_lora_weights()
 
 
 
 
 
 
125
 
 
 
 
 
 
 
 
 
 
 
126
  examples = [
127
  "a tiny astronaut hatching from an egg on the moon",
128
  "a cat holding a sign that says hello world",
129
  "an anime illustration of a wiener schnitzel",
130
  ]
131
-
132
  css = """
133
- #col-container {
134
- margin: 0 auto;
135
- max-width: 960px;
136
- }
137
- .generate-btn {
138
- background: linear-gradient(90deg, #4B79A1 0%, #283E51 100%) !important;
139
- border: none !important;
140
- color: white !important;
141
- }
142
- .generate-btn:hover {
143
- transform: translateY(-2px);
144
- box-shadow: 0 5px 15px rgba(0,0,0,0.2);
145
  }
146
  """
147
 
148
- with gr.Blocks(css=css) as app:
149
  gr.HTML("<center><h1>FLUX.1-Dev with LoRA support</h1></center>")
150
- with gr.Column(elem_id="col-container"):
151
  with gr.Row():
152
- with gr.Column():
153
  with gr.Row():
154
- text_prompt = gr.Textbox(label="Prompt", placeholder="Enter a prompt here", lines=3, elem_id="prompt-text-input")
155
  with gr.Row():
156
- custom_lora = gr.Textbox(label="Custom LoRA (optional)", info="LoRA Hugging Face path", placeholder="multimodalart/vintage-ads-flux")
157
  with gr.Row():
158
  with gr.Accordion("Advanced Settings", open=False):
159
- lora_scale = gr.Slider(
160
- label="LoRA Scale",
161
- minimum=0,
162
- maximum=2,
163
- step=0.01,
164
- value=0.95,
165
- )
166
- with gr.Row():
167
- width = gr.Slider(label="Width", value=1024, minimum=64, maximum=2048, step=8)
168
- height = gr.Slider(label="Height", value=1024, minimum=64, maximum=2048, step=8)
169
- seed = gr.Slider(label="Seed", value=-1, minimum=-1, maximum=4294967296, step=1)
170
- randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
171
- with gr.Row():
172
- steps = gr.Slider(label="Inference steps steps", value=28, minimum=1, maximum=100, step=1)
173
- cfg = gr.Slider(label="Guidance Scale", value=3.5, minimum=1, maximum=20, step=0.5)
174
- # method = gr.Radio(label="Sampling method", value="DPM++ 2M Karras", choices=["DPM++ 2M Karras", "DPM++ SDE Karras", "Euler", "Euler a", "Heun", "DDIM"])
175
 
176
- with gr.Row():
177
- # text_button = gr.Button("Run", variant='primary', elem_id="gen-button")
178
- text_button = gr.Button("✨ Generate Image", variant='primary', elem_classes=["generate-btn"])
179
- with gr.Column():
180
- with gr.Row():
181
- image_output = gr.Image(type="pil", label="Image Output", elem_id="gallery")
182
-
183
- # gr.Markdown(article_text)
184
- with gr.Column():
185
- gr.Examples(
186
- examples = examples,
187
- inputs = [text_prompt],
188
- )
189
- gr.on(
190
- triggers=[text_button.click, text_prompt.submit],
191
- fn = infer,
192
- inputs=[text_prompt, seed, randomize_seed, width, height, cfg, steps, custom_lora, lora_scale],
193
- outputs=[image_output, seed]
194
- )
195
 
196
- # text_button.click(query, inputs=[custom_lora, text_prompt, steps, cfg, randomize_seed, seed, width, height], outputs=[image_output,seed_output, seed])
197
- # text_button.click(infer, inputs=[text_prompt, seed, randomize_seed, width, height, cfg, steps, custom_lora, lora_scale], outputs=[image_output,seed_output, seed])
198
 
199
- app.launch(mcp_server=True, share=True)
 
1
  import gradio as gr
2
+ import requests
3
+ import io
4
  import random
 
 
 
 
 
 
 
 
5
  import os
6
+ import time
7
+ from PIL import Image
8
+ from deep_translator import GoogleTranslator
9
+ import json
10
+
11
+
12
+ API_TOKEN = os.getenv("HF_READ_TOKEN")
13
+ headers = {"Authorization": f"Bearer {API_TOKEN}"}
14
+ timeout = 100
15
+
16
+ def query(lora_id, prompt, is_negative=False, steps=28, cfg_scale=3.5, sampler="DPM++ 2M Karras", seed=-1, strength=0.7):
17
+ if prompt == "" or prompt == None:
18
+ return None
19
+
20
+ if lora_id.strip() == "" or lora_id == None:
21
+ lora_id = "black-forest-labs/FLUX.1-dev"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
+ key = random.randint(0, 999)
24
+
25
+ API_URL = "https://api-inference.huggingface.co/models/"+ lora_id.strip()
26
 
27
+ API_TOKEN = random.choice([os.getenv("HF_READ_TOKEN")])
28
+ headers = {"Authorization": f"Bearer {API_TOKEN}"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
+ prompt = GoogleTranslator(source='ru', target='en').translate(prompt)
31
+ print(f'\033[1mGeneration {key} translation:\033[0m {prompt}')
32
+
33
+ prompt = f"{prompt} | ultra detail, ultra elaboration, ultra quality, perfect."
34
+ print(f'\033[1mGeneration {key}:\033[0m {prompt}')
35
+
36
+ # If seed is -1, generate a random seed and use it
37
+ if seed == -1:
38
+ seed = random.randint(1, 1000000000)
39
+
40
+ payload = {
41
+ "inputs": prompt,
42
+ "steps": steps,
43
+ "cfg_scale": cfg_scale,
44
+ "seed": seed,
45
+ }
46
+
47
+ response = requests.post(API_URL, headers=headers, json=payload, timeout=timeout)
48
+ if response.status_code != 200:
49
+ print(f"Error: Failed to get image. Response status: {response.status_code}")
50
+ print(f"Response content: {response.text}")
51
+ if response.status_code == 503:
52
+ raise gr.Error(f"{response.status_code} : The model is being loaded")
53
+ raise gr.Error(f"{response.status_code}")
54
 
55
+ try:
56
+ image_bytes = response.content
57
+ image = Image.open(io.BytesIO(image_bytes))
58
+ print(f'\033[1mGeneration {key} completed!\033[0m ({prompt})')
59
+ return image, seed
60
+ except Exception as e:
61
+ print(f"Error when trying to open the image: {e}")
62
+ return None
63
+
64
+
65
  examples = [
66
  "a tiny astronaut hatching from an egg on the moon",
67
  "a cat holding a sign that says hello world",
68
  "an anime illustration of a wiener schnitzel",
69
  ]
70
+
71
  css = """
72
+ #app-container {
73
+ max-width: 600px;
74
+ margin-left: auto;
75
+ margin-right: auto;
 
 
 
 
 
 
 
 
76
  }
77
  """
78
 
79
+ with gr.Blocks(theme='Nymbo/Nymbo_Theme', css=css) as app:
80
  gr.HTML("<center><h1>FLUX.1-Dev with LoRA support</h1></center>")
81
+ with gr.Column(elem_id="app-container"):
82
  with gr.Row():
83
+ with gr.Column(elem_id="prompt-container"):
84
  with gr.Row():
85
+ text_prompt = gr.Textbox(label="Prompt", placeholder="Enter a prompt here", lines=2, elem_id="prompt-text-input")
86
  with gr.Row():
87
+ custom_lora = gr.Textbox(label="Custom LoRA", info="LoRA Hugging Face path (optional)", placeholder="multimodalart/vintage-ads-flux")
88
  with gr.Row():
89
  with gr.Accordion("Advanced Settings", open=False):
90
+ negative_prompt = gr.Textbox(label="Negative Prompt", placeholder="What should not be in the image", value="(deformed, distorted, disfigured), poorly drawn, bad anatomy, wrong anatomy, extra limb, missing limb, floating limbs, (mutated hands and fingers), disconnected limbs, mutation, mutated, ugly, disgusting, blurry, amputation, misspellings, typos", lines=3, elem_id="negative-prompt-text-input")
91
+ steps = gr.Slider(label="Sampling steps", value=28, minimum=1, maximum=100, step=1)
92
+ cfg = gr.Slider(label="CFG Scale", value=3.5, minimum=1, maximum=20, step=0.5)
93
+ method = gr.Radio(label="Sampling method", value="DPM++ 2M Karras", choices=["DPM++ 2M Karras", "DPM++ SDE Karras", "Euler", "Euler a", "Heun", "DDIM"])
94
+ strength = gr.Slider(label="Strength", value=0.7, minimum=0, maximum=1, step=0.001)
95
+ seed = gr.Slider(label="Seed", value=-1, minimum=-1, maximum=1000000000, step=1)
 
 
 
 
 
 
 
 
 
 
96
 
97
+ with gr.Row():
98
+ text_button = gr.Button("Run", variant='primary', elem_id="gen-button")
99
+ with gr.Row():
100
+ image_output = gr.Image(type="pil", label="Image Output", elem_id="gallery")
101
+ with gr.Row():
102
+ seed_output = gr.Textbox(label="Seed Used", show_copy_button = True, elem_id="seed-output")
103
+
104
+ gr.Examples(
105
+ examples = examples,
106
+ inputs = [text_prompt],
107
+ )
 
 
 
 
 
 
 
 
108
 
109
+ text_button.click(query, inputs=[custom_lora, text_prompt, negative_prompt, steps, cfg, method, seed, strength], outputs=[image_output,seed_output])
 
110
 
111
+ app.launch(show_api=False, share=False)
demo.py DELETED
@@ -1,199 +0,0 @@
1
- import gradio as gr
2
- import numpy as np
3
- import random
4
- # import spaces
5
- import torch
6
- from diffusers import DiffusionPipeline, FlowMatchEulerDiscreteScheduler, AutoencoderTiny, AutoencoderKL
7
- # from para_attn.first_block_cache.diffusers_adapters import apply_cache_on_pipe
8
- from transformers import CLIPTextModel, CLIPTokenizer,T5EncoderModel, T5TokenizerFast
9
- from live_preview_helpers import calculate_shift, retrieve_timesteps, flux_pipe_call_that_returns_an_iterable_of_images
10
- import multiprocessing as mp
11
-
12
- import os
13
- import requests
14
- import tempfile
15
- import shutil
16
- from urllib.parse import urlparse
17
-
18
- dtype = torch.bfloat16
19
- device = "cuda" if torch.cuda.is_available() else "cpu"
20
- #black-forest-labs/FLUX.1-Krea-dev
21
- taef1 = AutoencoderTiny.from_pretrained("madebyollin/taef1", torch_dtype=dtype).to(device)
22
- good_vae = AutoencoderKL.from_pretrained("black-forest-labs/FLUX.1-dev", subfolder="vae", torch_dtype=dtype).to(device)
23
- pipe = DiffusionPipeline.from_pretrained("black-forest-labs/FLUX.1-dev", torch_dtype=dtype, vae=taef1).to(device)
24
- # srpo_128_base_oficial_model_fp16.safetensors
25
- # pipe.load_lora_weights('Alissonerdx/flux.1-dev-SRPO-LoRas', weight_name='srpo_16_base_oficial_model_fp16.safetensors')
26
- # pipe.fuse_lora()
27
- torch.cuda.empty_cache()
28
-
29
- MAX_SEED = np.iinfo(np.int32).max
30
- MAX_IMAGE_SIZE = 2048
31
-
32
- pipe.flux_pipe_call_that_returns_an_iterable_of_images = flux_pipe_call_that_returns_an_iterable_of_images.__get__(pipe)
33
-
34
- def load_lora_auto(pipe, lora_input):
35
- lora_input = lora_input.strip()
36
- if not lora_input:
37
- return
38
-
39
- # If it's just an ID like "author/model"
40
- if "/" in lora_input and not lora_input.startswith("http"):
41
- pipe.load_lora_weights(lora_input)
42
- return
43
-
44
- if lora_input.startswith("http"):
45
- url = lora_input
46
-
47
- # Repo page (no blob/resolve)
48
- if "huggingface.co" in url and "/blob/" not in url and "/resolve/" not in url:
49
- repo_id = urlparse(url).path.strip("/")
50
- pipe.load_lora_weights(repo_id)
51
- return
52
-
53
- # Blob link → convert to resolve link
54
- if "/blob/" in url:
55
- url = url.replace("/blob/", "/resolve/")
56
-
57
- # Download direct file
58
- tmp_dir = tempfile.mkdtemp()
59
- local_path = os.path.join(tmp_dir, os.path.basename(urlparse(url).path))
60
-
61
- try:
62
- print(f"Downloading LoRA from {url}...")
63
- resp = requests.get(url, stream=True)
64
- resp.raise_for_status()
65
- with open(local_path, "wb") as f:
66
- for chunk in resp.iter_content(chunk_size=8192):
67
- f.write(chunk)
68
- print(f"Saved LoRA to {local_path}")
69
- pipe.load_lora_weights(local_path)
70
- finally:
71
- shutil.rmtree(tmp_dir, ignore_errors=True)
72
-
73
- # @spaces.GPU(duration=25)
74
- def infer(prompt, seed=42, randomize_seed=False, width=1024, height=1024, guidance_scale=3.5, num_inference_steps=28, lora_id=None, lora_scale=0.95, progress=gr.Progress(track_tqdm=True)):
75
- if randomize_seed:
76
- seed = random.randint(0, MAX_SEED)
77
- generator = torch.Generator().manual_seed(seed)
78
-
79
-
80
- # for img in pipe.flux_pipe_call_that_returns_an_iterable_of_images(
81
- # prompt=prompt,
82
- # guidance_scale=guidance_scale,
83
- # num_inference_steps=num_inference_steps,
84
- # width=width,
85
- # height=height,
86
- # generator=generator,
87
- # output_type="pil",
88
- # good_vae=good_vae,
89
- # ):
90
- # yield img, seed
91
-
92
- # Handle LoRA loading
93
- # Load LoRA weights and prepare joint_attention_kwargs
94
- if lora_id and lora_id.strip() != "":
95
- pipe.unload_lora_weights()
96
- # pipe.load_lora_weights(lora_id.strip())
97
- load_lora_auto(pipe, lora_id.strip())
98
- joint_attention_kwargs = {"scale": lora_scale}
99
- else:
100
- joint_attention_kwargs = None
101
-
102
- # apply_cache_on_pipe(
103
- # pipe,
104
- # # residual_diff_threshold=0.2,
105
- # )
106
-
107
- try:
108
- # Call the custom pipeline function with the correct keyword argument
109
- for img in pipe.flux_pipe_call_that_returns_an_iterable_of_images(
110
- prompt=prompt,
111
- guidance_scale=guidance_scale,
112
- num_inference_steps=num_inference_steps,
113
- width=width,
114
- height=height,
115
- generator=generator,
116
- output_type="pil",
117
- good_vae=good_vae, # Assuming good_vae is defined elsewhere
118
- joint_attention_kwargs=joint_attention_kwargs, # Fixed parameter name
119
- ):
120
- yield img, seed
121
- finally:
122
- # Unload LoRA weights if they were loaded
123
- if lora_id:
124
- pipe.unload_lora_weights()
125
-
126
- examples = [
127
- "a tiny astronaut hatching from an egg on the moon",
128
- "a cat holding a sign that says hello world",
129
- "an anime illustration of a wiener schnitzel",
130
- ]
131
-
132
- css = """
133
- #col-container {
134
- margin: 0 auto;
135
- max-width: 960px;
136
- }
137
- .generate-btn {
138
- background: linear-gradient(90deg, #4B79A1 0%, #283E51 100%) !important;
139
- border: none !important;
140
- color: white !important;
141
- }
142
- .generate-btn:hover {
143
- transform: translateY(-2px);
144
- box-shadow: 0 5px 15px rgba(0,0,0,0.2);
145
- }
146
- """
147
-
148
- with gr.Blocks(css=css) as app:
149
- gr.HTML("<center><h1>FLUX.1-Dev with LoRA support</h1></center>")
150
- with gr.Column(elem_id="col-container"):
151
- with gr.Row():
152
- with gr.Column():
153
- with gr.Row():
154
- text_prompt = gr.Textbox(label="Prompt", placeholder="Enter a prompt here", lines=3, elem_id="prompt-text-input")
155
- with gr.Row():
156
- custom_lora = gr.Textbox(label="Custom LoRA (optional)", info="LoRA Hugging Face path", placeholder="multimodalart/vintage-ads-flux")
157
- with gr.Row():
158
- with gr.Accordion("Advanced Settings", open=False):
159
- lora_scale = gr.Slider(
160
- label="LoRA Scale",
161
- minimum=0,
162
- maximum=2,
163
- step=0.01,
164
- value=0.95,
165
- )
166
- with gr.Row():
167
- width = gr.Slider(label="Width", value=1024, minimum=64, maximum=2048, step=8)
168
- height = gr.Slider(label="Height", value=1024, minimum=64, maximum=2048, step=8)
169
- seed = gr.Slider(label="Seed", value=-1, minimum=-1, maximum=4294967296, step=1)
170
- randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
171
- with gr.Row():
172
- steps = gr.Slider(label="Inference steps steps", value=28, minimum=1, maximum=100, step=1)
173
- cfg = gr.Slider(label="Guidance Scale", value=3.5, minimum=1, maximum=20, step=0.5)
174
- # method = gr.Radio(label="Sampling method", value="DPM++ 2M Karras", choices=["DPM++ 2M Karras", "DPM++ SDE Karras", "Euler", "Euler a", "Heun", "DDIM"])
175
-
176
- with gr.Row():
177
- # text_button = gr.Button("Run", variant='primary', elem_id="gen-button")
178
- text_button = gr.Button("✨ Generate Image", variant='primary', elem_classes=["generate-btn"])
179
- with gr.Column():
180
- with gr.Row():
181
- image_output = gr.Image(type="pil", label="Image Output", elem_id="gallery")
182
-
183
- # gr.Markdown(article_text)
184
- with gr.Column():
185
- gr.Examples(
186
- examples = examples,
187
- inputs = [text_prompt],
188
- )
189
- gr.on(
190
- triggers=[text_button.click, text_prompt.submit],
191
- fn = infer,
192
- inputs=[text_prompt, seed, randomize_seed, width, height, cfg, steps, custom_lora, lora_scale],
193
- outputs=[image_output, seed]
194
- )
195
-
196
- # text_button.click(query, inputs=[custom_lora, text_prompt, steps, cfg, randomize_seed, seed, width, height], outputs=[image_output,seed_output, seed])
197
- # text_button.click(infer, inputs=[text_prompt, seed, randomize_seed, width, height, cfg, steps, custom_lora, lora_scale], outputs=[image_output,seed_output, seed])
198
-
199
- app.launch(share=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
live_preview_helpers.py DELETED
@@ -1,166 +0,0 @@
1
- import torch
2
- import numpy as np
3
- from diffusers import FluxPipeline, AutoencoderTiny, FlowMatchEulerDiscreteScheduler
4
- from typing import Any, Dict, List, Optional, Union
5
-
6
- # Helper functions
7
- def calculate_shift(
8
- image_seq_len,
9
- base_seq_len: int = 256,
10
- max_seq_len: int = 4096,
11
- base_shift: float = 0.5,
12
- max_shift: float = 1.16,
13
- ):
14
- m = (max_shift - base_shift) / (max_seq_len - base_seq_len)
15
- b = base_shift - m * base_seq_len
16
- mu = image_seq_len * m + b
17
- return mu
18
-
19
- def retrieve_timesteps(
20
- scheduler,
21
- num_inference_steps: Optional[int] = None,
22
- device: Optional[Union[str, torch.device]] = None,
23
- timesteps: Optional[List[int]] = None,
24
- sigmas: Optional[List[float]] = None,
25
- **kwargs,
26
- ):
27
- if timesteps is not None and sigmas is not None:
28
- raise ValueError("Only one of `timesteps` or `sigmas` can be passed. Please choose one to set custom values")
29
- if timesteps is not None:
30
- scheduler.set_timesteps(timesteps=timesteps, device=device, **kwargs)
31
- timesteps = scheduler.timesteps
32
- num_inference_steps = len(timesteps)
33
- elif sigmas is not None:
34
- scheduler.set_timesteps(sigmas=sigmas, device=device, **kwargs)
35
- timesteps = scheduler.timesteps
36
- num_inference_steps = len(timesteps)
37
- else:
38
- scheduler.set_timesteps(num_inference_steps, device=device, **kwargs)
39
- timesteps = scheduler.timesteps
40
- return timesteps, num_inference_steps
41
-
42
- # FLUX pipeline function
43
- @torch.inference_mode()
44
- def flux_pipe_call_that_returns_an_iterable_of_images(
45
- self,
46
- prompt: Union[str, List[str]] = None,
47
- prompt_2: Optional[Union[str, List[str]]] = None,
48
- height: Optional[int] = None,
49
- width: Optional[int] = None,
50
- num_inference_steps: int = 28,
51
- timesteps: List[int] = None,
52
- guidance_scale: float = 3.5,
53
- num_images_per_prompt: Optional[int] = 1,
54
- generator: Optional[Union[torch.Generator, List[torch.Generator]]] = None,
55
- latents: Optional[torch.FloatTensor] = None,
56
- prompt_embeds: Optional[torch.FloatTensor] = None,
57
- pooled_prompt_embeds: Optional[torch.FloatTensor] = None,
58
- output_type: Optional[str] = "pil",
59
- return_dict: bool = True,
60
- joint_attention_kwargs: Optional[Dict[str, Any]] = None,
61
- max_sequence_length: int = 512,
62
- good_vae: Optional[Any] = None,
63
- ):
64
- height = height or self.default_sample_size * self.vae_scale_factor
65
- width = width or self.default_sample_size * self.vae_scale_factor
66
-
67
- # 1. Check inputs
68
- self.check_inputs(
69
- prompt,
70
- prompt_2,
71
- height,
72
- width,
73
- prompt_embeds=prompt_embeds,
74
- pooled_prompt_embeds=pooled_prompt_embeds,
75
- max_sequence_length=max_sequence_length,
76
- )
77
-
78
- self._guidance_scale = guidance_scale
79
- self._joint_attention_kwargs = joint_attention_kwargs
80
- self._interrupt = False
81
-
82
- # 2. Define call parameters
83
- batch_size = 1 if isinstance(prompt, str) else len(prompt)
84
- device = self._execution_device
85
-
86
- # 3. Encode prompt
87
- lora_scale = joint_attention_kwargs.get("scale", None) if joint_attention_kwargs is not None else None
88
- prompt_embeds, pooled_prompt_embeds, text_ids = self.encode_prompt(
89
- prompt=prompt,
90
- prompt_2=prompt_2,
91
- prompt_embeds=prompt_embeds,
92
- pooled_prompt_embeds=pooled_prompt_embeds,
93
- device=device,
94
- num_images_per_prompt=num_images_per_prompt,
95
- max_sequence_length=max_sequence_length,
96
- lora_scale=lora_scale,
97
- )
98
- # 4. Prepare latent variables
99
- num_channels_latents = self.transformer.config.in_channels // 4
100
- latents, latent_image_ids = self.prepare_latents(
101
- batch_size * num_images_per_prompt,
102
- num_channels_latents,
103
- height,
104
- width,
105
- prompt_embeds.dtype,
106
- device,
107
- generator,
108
- latents,
109
- )
110
- # 5. Prepare timesteps
111
- sigmas = np.linspace(1.0, 1 / num_inference_steps, num_inference_steps)
112
- image_seq_len = latents.shape[1]
113
- mu = calculate_shift(
114
- image_seq_len,
115
- self.scheduler.config.base_image_seq_len,
116
- self.scheduler.config.max_image_seq_len,
117
- self.scheduler.config.base_shift,
118
- self.scheduler.config.max_shift,
119
- )
120
- timesteps, num_inference_steps = retrieve_timesteps(
121
- self.scheduler,
122
- num_inference_steps,
123
- device,
124
- timesteps,
125
- sigmas,
126
- mu=mu,
127
- )
128
- self._num_timesteps = len(timesteps)
129
-
130
- # Handle guidance
131
- guidance = torch.full([1], guidance_scale, device=device, dtype=torch.float32).expand(latents.shape[0]) if self.transformer.config.guidance_embeds else None
132
-
133
- # 6. Denoising loop
134
- for i, t in enumerate(timesteps):
135
- if self.interrupt:
136
- continue
137
-
138
- timestep = t.expand(latents.shape[0]).to(latents.dtype)
139
-
140
- noise_pred = self.transformer(
141
- hidden_states=latents,
142
- timestep=timestep / 1000,
143
- guidance=guidance,
144
- pooled_projections=pooled_prompt_embeds,
145
- encoder_hidden_states=prompt_embeds,
146
- txt_ids=text_ids,
147
- img_ids=latent_image_ids,
148
- joint_attention_kwargs=self.joint_attention_kwargs,
149
- return_dict=False,
150
- )[0]
151
- # Yield intermediate result
152
- latents_for_image = self._unpack_latents(latents, height, width, self.vae_scale_factor)
153
- latents_for_image = (latents_for_image / self.vae.config.scaling_factor) + self.vae.config.shift_factor
154
- image = self.vae.decode(latents_for_image, return_dict=False)[0]
155
- yield self.image_processor.postprocess(image, output_type=output_type)[0]
156
-
157
- latents = self.scheduler.step(noise_pred, t, latents, return_dict=False)[0]
158
- torch.cuda.empty_cache()
159
-
160
- # Final image using good_vae
161
- latents = self._unpack_latents(latents, height, width, self.vae_scale_factor)
162
- latents = (latents / good_vae.config.scaling_factor) + good_vae.config.shift_factor
163
- image = good_vae.decode(latents, return_dict=False)[0]
164
- self.maybe_free_model_hooks()
165
- torch.cuda.empty_cache()
166
- yield self.image_processor.postprocess(image, output_type=output_type)[0]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
requirements.txt CHANGED
@@ -1,8 +1,4 @@
1
- accelerate
2
- diffusers==0.34.0
3
- torch
4
- para-attn
5
- transformers==4.48.3
6
- xformers
7
- sentencepiece
8
- peft==0.17.1
 
1
+ requests
2
+ pillow
3
+ deep-translator
4
+ langdetect