Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,18 +1,9 @@
|
|
1 |
-
import spaces # beginn
|
2 |
import torch.multiprocessing as mp
|
3 |
import torch
|
4 |
import os
|
5 |
-
import pandas as pd
|
6 |
-
import gc
|
7 |
import re
|
8 |
import random
|
9 |
-
from tqdm.auto import tqdm
|
10 |
from collections import deque
|
11 |
-
from optimum.quanto import freeze, qfloat8, quantize
|
12 |
-
from diffusers import FlowMatchEulerDiscreteScheduler, AutoencoderKL
|
13 |
-
from diffusers.models.transformers.transformer_flux import FluxTransformer2DModel
|
14 |
-
from diffusers.pipelines.flux.pipeline_flux import FluxPipeline
|
15 |
-
from transformers import CLIPTextModel, CLIPTokenizer, T5EncoderModel, T5TokenizerFast
|
16 |
from transformers import pipeline, AutoModelForCausalLM, AutoTokenizer
|
17 |
import gradio as gr
|
18 |
from accelerate import Accelerator
|
@@ -30,40 +21,56 @@ dtype = torch.bfloat16
|
|
30 |
os.environ['FLUX_DEV'] = '.'
|
31 |
os.environ['AE'] = '.'
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
)
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
def generate_description_prompt(subject, user_prompt, text_generator):
|
68 |
prompt = f"write concise vivid visual description enclosed in brackets like [ <description> ] less than 100 words of {user_prompt} different from {subject}. "
|
69 |
try:
|
@@ -74,33 +81,17 @@ def generate_description_prompt(subject, user_prompt, text_generator):
|
|
74 |
print(f"Error generating description for subject '{subject}': {e}")
|
75 |
return None
|
76 |
|
77 |
-
# Function to parse descriptions from a given text
|
78 |
def parse_descriptions(text):
|
79 |
-
# Find all descriptions enclosed in brackets
|
80 |
descriptions = re.findall(r'\[([^\[\]]+)\]', text)
|
81 |
-
# Filter descriptions with at least 3 words
|
82 |
descriptions = [desc.strip() for desc in descriptions if len(desc.split()) >= 3]
|
83 |
return descriptions
|
84 |
|
85 |
-
# Seed words pool
|
86 |
-
seed_words = []
|
87 |
-
|
88 |
-
used_words = set()
|
89 |
-
|
90 |
-
# Queue to store parsed descriptions
|
91 |
-
parsed_descriptions_queue = deque()
|
92 |
-
|
93 |
-
# Usage limits
|
94 |
-
MAX_DESCRIPTIONS = 30
|
95 |
-
MAX_IMAGES = 12
|
96 |
-
|
97 |
@spaces.GPU
|
98 |
def generate_descriptions(user_prompt, seed_words_input, batch_size=100, max_iterations=50):
|
99 |
descriptions = []
|
100 |
description_queue = deque()
|
101 |
iteration_count = 0
|
102 |
|
103 |
-
# Initialize the text generation pipeline with 16-bit precision
|
104 |
print("Initializing the text generation pipeline with 16-bit precision...")
|
105 |
model_name = 'meta-llama/Meta-Llama-3.1-8B-Instruct'
|
106 |
model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float16, device_map='auto')
|
@@ -108,11 +99,9 @@ def generate_descriptions(user_prompt, seed_words_input, batch_size=100, max_ite
|
|
108 |
text_generator = pipeline('text-generation', model=model, tokenizer=tokenizer)
|
109 |
print("Text generation pipeline initialized with 16-bit precision.")
|
110 |
|
111 |
-
# Populate the seed_words array with user input
|
112 |
seed_words.extend(re.findall(r'"(.*?)"', seed_words_input))
|
113 |
|
114 |
while iteration_count < max_iterations and len(parsed_descriptions_queue) < MAX_DESCRIPTIONS:
|
115 |
-
# Select a subject that has not been used
|
116 |
available_subjects = [word for word in seed_words if word not in used_words]
|
117 |
if not available_subjects:
|
118 |
print("No more available subjects to use.")
|
@@ -122,18 +111,14 @@ def generate_descriptions(user_prompt, seed_words_input, batch_size=100, max_ite
|
|
122 |
generated_description = generate_description_prompt(subject, user_prompt, text_generator)
|
123 |
|
124 |
if generated_description:
|
125 |
-
# Remove any offending symbols
|
126 |
clean_description = generated_description.encode('ascii', 'ignore').decode('ascii')
|
127 |
description_queue.append({'subject': subject, 'description': clean_description})
|
128 |
|
129 |
-
# Print the generated description to the command line
|
130 |
print(f"Generated description for subject '{subject}': {clean_description}")
|
131 |
|
132 |
-
# Update used words and seed words
|
133 |
used_words.add(subject)
|
134 |
-
seed_words.append(clean_description)
|
135 |
|
136 |
-
# Parse and append descriptions every 3 iterations
|
137 |
if iteration_count % 3 == 0:
|
138 |
parsed_descriptions = parse_descriptions(clean_description)
|
139 |
parsed_descriptions_queue.extend(parsed_descriptions)
|
@@ -143,28 +128,25 @@ def generate_descriptions(user_prompt, seed_words_input, batch_size=100, max_ite
|
|
143 |
return list(parsed_descriptions_queue)
|
144 |
|
145 |
@spaces.GPU(duration=120)
|
146 |
-
def generate_images(parsed_descriptions):
|
147 |
-
# If there are fewer than MAX_IMAGES descriptions, use whatever is available
|
148 |
if len(parsed_descriptions) < MAX_IMAGES:
|
149 |
prompts = parsed_descriptions
|
150 |
else:
|
151 |
prompts = [parsed_descriptions.pop(0) for _ in range(MAX_IMAGES)]
|
152 |
|
153 |
-
# Generate images from the parsed descriptions
|
154 |
images = []
|
155 |
for prompt in prompts:
|
156 |
images.extend(pipe(prompt, num_images=1).images)
|
157 |
|
158 |
return images
|
159 |
|
160 |
-
# Create Gradio Interface
|
161 |
def combined_function(user_prompt, seed_words_input):
|
162 |
parsed_descriptions = generate_descriptions(user_prompt, seed_words_input)
|
163 |
-
|
|
|
164 |
return images
|
165 |
|
166 |
if __name__ == '__main__':
|
167 |
-
# Ensure CUDA is initialized correctly
|
168 |
torch.cuda.init()
|
169 |
|
170 |
interface = gr.Interface(
|
@@ -173,4 +155,4 @@ if __name__ == '__main__':
|
|
173 |
outputs=gr.Gallery()
|
174 |
)
|
175 |
|
176 |
-
interface.launch()
|
|
|
|
|
1 |
import torch.multiprocessing as mp
|
2 |
import torch
|
3 |
import os
|
|
|
|
|
4 |
import re
|
5 |
import random
|
|
|
6 |
from collections import deque
|
|
|
|
|
|
|
|
|
|
|
7 |
from transformers import pipeline, AutoModelForCausalLM, AutoTokenizer
|
8 |
import gradio as gr
|
9 |
from accelerate import Accelerator
|
|
|
21 |
os.environ['FLUX_DEV'] = '.'
|
22 |
os.environ['AE'] = '.'
|
23 |
|
24 |
+
# Seed words pool
|
25 |
+
seed_words = []
|
26 |
+
|
27 |
+
used_words = set()
|
28 |
+
|
29 |
+
# Queue to store parsed descriptions
|
30 |
+
parsed_descriptions_queue = deque()
|
31 |
+
|
32 |
+
# Usage limits
|
33 |
+
MAX_DESCRIPTIONS = 30
|
34 |
+
MAX_IMAGES = 12
|
35 |
+
|
36 |
+
def initialize_diffusers():
|
37 |
+
from optimum.quanto import freeze, qfloat8, quantize
|
38 |
+
from diffusers import FlowMatchEulerDiscreteScheduler, AutoencoderKL
|
39 |
+
from diffusers.models.transformers.transformer_flux import FluxTransformer2DModel
|
40 |
+
from diffusers.pipelines.flux.pipeline_flux import FluxPipeline
|
41 |
+
from transformers import CLIPTextModel, CLIPTokenizer, T5EncoderModel, T5TokenizerFast
|
42 |
+
|
43 |
+
bfl_repo = 'black-forest-labs/FLUX.1-schnell'
|
44 |
+
revision = 'refs/pr/1'
|
45 |
+
|
46 |
+
scheduler = FlowMatchEulerDiscreteScheduler.from_pretrained(bfl_repo, subfolder='scheduler', revision=revision)
|
47 |
+
text_encoder = CLIPTextModel.from_pretrained('openai/clip-vit-large-patch14', torch_dtype=dtype)
|
48 |
+
tokenizer = CLIPTokenizer.from_pretrained('openai/clip-vit-large-patch14', torch_dtype=dtype)
|
49 |
+
text_encoder_2 = T5EncoderModel.from_pretrained(bfl_repo, subfolder='text_encoder_2', torch_dtype=dtype, revision=revision)
|
50 |
+
tokenizer_2 = T5TokenizerFast.from_pretrained(bfl_repo, subfolder='tokenizer_2', torch_dtype=dtype, revision=revision)
|
51 |
+
vae = AutoencoderKL.from_pretrained(bfl_repo, subfolder='vae', torch_dtype=dtype, revision=revision)
|
52 |
+
transformer = FluxTransformer2DModel.from_pretrained(bfl_repo, subfolder='transformer', torch_dtype=dtype, revision=revision)
|
53 |
+
|
54 |
+
quantize(transformer, weights=qfloat8)
|
55 |
+
freeze(transformer)
|
56 |
+
quantize(text_encoder_2, weights=qfloat8)
|
57 |
+
freeze(text_encoder_2)
|
58 |
+
|
59 |
+
pipe = FluxPipeline(
|
60 |
+
scheduler=scheduler,
|
61 |
+
text_encoder=text_encoder,
|
62 |
+
tokenizer=tokenizer,
|
63 |
+
text_encoder_2=None,
|
64 |
+
tokenizer_2=tokenizer_2,
|
65 |
+
vae=vae,
|
66 |
+
transformer=None,
|
67 |
+
)
|
68 |
+
pipe.text_encoder_2 = text_encoder_2
|
69 |
+
pipe.transformer = transformer
|
70 |
+
pipe.enable_model_cpu_offload()
|
71 |
+
|
72 |
+
return pipe
|
73 |
+
|
74 |
def generate_description_prompt(subject, user_prompt, text_generator):
|
75 |
prompt = f"write concise vivid visual description enclosed in brackets like [ <description> ] less than 100 words of {user_prompt} different from {subject}. "
|
76 |
try:
|
|
|
81 |
print(f"Error generating description for subject '{subject}': {e}")
|
82 |
return None
|
83 |
|
|
|
84 |
def parse_descriptions(text):
|
|
|
85 |
descriptions = re.findall(r'\[([^\[\]]+)\]', text)
|
|
|
86 |
descriptions = [desc.strip() for desc in descriptions if len(desc.split()) >= 3]
|
87 |
return descriptions
|
88 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
@spaces.GPU
|
90 |
def generate_descriptions(user_prompt, seed_words_input, batch_size=100, max_iterations=50):
|
91 |
descriptions = []
|
92 |
description_queue = deque()
|
93 |
iteration_count = 0
|
94 |
|
|
|
95 |
print("Initializing the text generation pipeline with 16-bit precision...")
|
96 |
model_name = 'meta-llama/Meta-Llama-3.1-8B-Instruct'
|
97 |
model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float16, device_map='auto')
|
|
|
99 |
text_generator = pipeline('text-generation', model=model, tokenizer=tokenizer)
|
100 |
print("Text generation pipeline initialized with 16-bit precision.")
|
101 |
|
|
|
102 |
seed_words.extend(re.findall(r'"(.*?)"', seed_words_input))
|
103 |
|
104 |
while iteration_count < max_iterations and len(parsed_descriptions_queue) < MAX_DESCRIPTIONS:
|
|
|
105 |
available_subjects = [word for word in seed_words if word not in used_words]
|
106 |
if not available_subjects:
|
107 |
print("No more available subjects to use.")
|
|
|
111 |
generated_description = generate_description_prompt(subject, user_prompt, text_generator)
|
112 |
|
113 |
if generated_description:
|
|
|
114 |
clean_description = generated_description.encode('ascii', 'ignore').decode('ascii')
|
115 |
description_queue.append({'subject': subject, 'description': clean_description})
|
116 |
|
|
|
117 |
print(f"Generated description for subject '{subject}': {clean_description}")
|
118 |
|
|
|
119 |
used_words.add(subject)
|
120 |
+
seed_words.append(clean_description)
|
121 |
|
|
|
122 |
if iteration_count % 3 == 0:
|
123 |
parsed_descriptions = parse_descriptions(clean_description)
|
124 |
parsed_descriptions_queue.extend(parsed_descriptions)
|
|
|
128 |
return list(parsed_descriptions_queue)
|
129 |
|
130 |
@spaces.GPU(duration=120)
|
131 |
+
def generate_images(parsed_descriptions, pipe):
|
|
|
132 |
if len(parsed_descriptions) < MAX_IMAGES:
|
133 |
prompts = parsed_descriptions
|
134 |
else:
|
135 |
prompts = [parsed_descriptions.pop(0) for _ in range(MAX_IMAGES)]
|
136 |
|
|
|
137 |
images = []
|
138 |
for prompt in prompts:
|
139 |
images.extend(pipe(prompt, num_images=1).images)
|
140 |
|
141 |
return images
|
142 |
|
|
|
143 |
def combined_function(user_prompt, seed_words_input):
|
144 |
parsed_descriptions = generate_descriptions(user_prompt, seed_words_input)
|
145 |
+
pipe = initialize_diffusers()
|
146 |
+
images = generate_images(parsed_descriptions, pipe)
|
147 |
return images
|
148 |
|
149 |
if __name__ == '__main__':
|
|
|
150 |
torch.cuda.init()
|
151 |
|
152 |
interface = gr.Interface(
|
|
|
155 |
outputs=gr.Gallery()
|
156 |
)
|
157 |
|
158 |
+
interface.launch()
|